为了账号安全,请及时绑定邮箱和手机立即绑定

如何将 Spring 上下文作为方法参数传递?

如何将 Spring 上下文作为方法参数传递?

Smart猫小萌 2021-11-11 18:08:53
我需要一些有关 Spring 的帮助(SpringBoot 1.3.2.RELEASE、Spring 4.3.11.RELEASE)。用例很特殊,需要解释。我有一个 Spring 应用程序管理客户发送的请求。为了处理这些请求,我们需要使用@Autowired 注解声明的服务。非常经典。最近,我们决定处理来自其他国家/地区的新型请求。关键是为了面对不同的情况和类型的请求,我们决定实现一个策略模式。-> 根据请求的类型,我们执行在运行时选择的策略。每个策略都包含在一个具体的类中,并且所有策略共享相同的接口。所以,我有:一个主类,其中请求处理完成。为了完成它的工作,这个类曾经调用一些用@Autowired 注释声明的服务。我现在有 :一个只初始化请求处理的主类。为了完成它的工作,这个类将在运行时根据一些标准实例化一个单一的策略。带有 2 个方法的 IStrategy(接口)将由我的 2 个具体类实现2 个具体的类(以及更多的类)可以完成这项工作。非常重要的一点是,这些具体的类将在运行时实例化,在 Spring 上下文加载之后。问题是在加载 Spring 上下文之后,就不能再使用 @Autowired 注释了。 我想在具体策略类中使用的所有服务都不能再被 @Autowired 调用并保持为 NULL。我通过将我需要的服务作为参数传递给我的具体策略类找到了一种解决方法,但是我必须作为参数传递的服务数量因一种策略而异。我认为我应该传递整个 Spring 上下文,但我不知道该怎么做。而且我也不知道如何从上下文访问所有带注释的服务。PS:我不显示代码行,因为我认为实际上没有必要。如果您认为代码会更明确,我会发送一些。提前感谢。
查看完整描述

3 回答

?
不负相思意

TA贡献1777条经验 获得超10个赞

您可以使用下面的类来静态获取应用程序上下文和 Bean


import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Service;


@Service

public class BeanUtil implements ApplicationContextAware {


    private static ApplicationContext context;

    @Override

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        context = applicationContext;

    }

    public static <T> T getBean(Class<T> beanClass) {

        return context.getBean(beanClass);

    }




}


查看完整回答
反对 回复 2021-11-11
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

您应该声明一个工厂来映射依赖项,而不是将服务声明为 bean,它会在将服务的具体实例返回给注入器之前检查请求。看看这里:

https://grokonez.com/spring-framework/spring-core/use-spring-factory-method-create-spring-bean


查看完整回答
反对 回复 2021-11-11
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

大家好,他们很快就回复了我。首先,我必须为最近回复您所有的评论而道歉。最后一个冲刺是一个很大的负荷,新的也好不到哪里去^^


我需要在 Spring 上下文完成后创建对象以创建和加载应用程序的所有部分。作为策略模式的一部分,我必须在运行时实例化一个类,具体取决于在我必须处理的请求文件中找到的一些值。此类需要使用@Autowired注释声明的许多服务,但所有自动装配的对象仍为“ null”,因为在加载上下文后调用。


这是我首先想使用的代码。没有 Spring 也可以。


Function<Document, IStrategy> func = doc -> {

        String strategyToApply = "";

        IStrategy strategy = null;

        switch(doc.getPlace()) {

            case "Paris":

                strategyToApply = "strategies_classes.ProcessParis";

                break;

            case "New York":

                strategyToApply = "strategies_classes.ProcessNewYork";

                break;

            }

            case "Roma":

                ...

        try {

            **Class<?> classToUse = Class.forName(strategyToApply);

            strategy = (IStrategy) classToUse.newInstance();**

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        } catch (InstantiationException e) {

            e.printStackTrace();

        } catch (IllegalAccessException e) {

            e.printStackTrace();

        }

        return strategy;

};


Consumer<Document> consumerStrategy = doc -> {

    IStrategy strategy = func.apply(doc);

    strategy.bookRequest(doc);

};

documents.stream()

    .forEach(consumerStrategy);

我终于找到了神奇的物体。当 Spring 对象的生命周期不符合我们自己的概念时,这是一个很好的解决方法。


要使用它,您只需使用 @Autowired 声明它:


@Autowired

private AutowireCapableBeanFactory autowireBeanFactory;

请注意, AutowireCapableBeanFactory 是一个 Spring 对象,您无需在其他任何地方声明!


然后,要使用它,很简单(我设计了一个与您在上面看到的非常不同的全新服务,但它的作用相同):


public <T> T getStrategyToUse(Entity bookingCtr, Funder funder, StrategyEnum strategy) throws FunctionalException {

        String strategyToApply = null;

        strategyToApply = strategyDao.getClassToApply(bookingCtr, funder, strategy);

        Class<?> classToUse;

        try {

            classToUse = Class.forName(strategyToApply);

            T strat = (T) **autowireBeanFactory.getBean**(classToUse);

            return (T) strat;

        } catch (ClassNotFoundException e) {

            LOGGER.error("The indicated Strategy class was not found", e);

        }

        return null;

    }

在运行时加载时,所选类将毫无问题地实例化,并且其所有自动装配的对象不再为空。


我希望这将有所帮助。


查看完整回答
反对 回复 2021-11-11
  • 3 回答
  • 0 关注
  • 354 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信