【问题标题】:ContextSingletonBeanFactoryLocator alternative in spring 5Spring 5 中的 ContextSingletonBeanFactoryLocator 替代方案
【发布时间】:2018-01-25 06:00:47
【问题描述】:

我们使用的是 4.2.x 版本的 spring,我们正在使用 ContextSingletonBeanFactoryLocator 来加载 bean,如下所示

BeanFactoryLocator bfLocator = ContextSingletonBeanFactoryLocator.getInstance("classpath:customBeanRefFactory.xml");
BeanFactoryReference ref = bfLocator.useBeanFactory("sharedApplicationContext");
BeanFactory beanFactory = ref.getFactory();
((AbstractApplicationContext) beanFactory).getBeanFactory().setBeanClassLoader(CustomSpringBeanFactory.class.getClassLoader());
return (ApplicationContext) beanFactory

我们计划升级到 spring 5.0.x 并发现 ContextSingletonBeanFactoryLocator 以及 BeanFactoryLocator 和 BeanFactoryReference 等类从 spring 5.0 版本中删除。

那么获得应用程序上下文的建议替代方法是什么?

@Configuration
@ImportResource("classpath:ourxml")
public class OurApplicationConfiguration {

}


public class OurAppicationFactoryProvider {

    ApplicationContext context;

    public ApplicationContext getApplicationContext() {
        if (context == null) {
            synchronized (this) {
                if (context == null) {
                    context = new AnnotationConfigApplicationContext(OurApplicationConfiguration.class);
                }
            }
        }
        return context;
    }
}

这是正确的方法还是有其他选择?

【问题讨论】:

  • 基本上你得到ApplicationContext的事实已经是一个缺陷,在应用程序中你不应该需要它(假设Spring正在创建上下文)。您的“解决方案”使情况变得更糟,因为这将加载两次上下文(假设 Spring 也在实例化上下文)。
  • 我们很少有没有被spring注解的遗留bean。所以我们使用应用程序上下文来获取它们
  • 遗留 bean 没有注释但通过上下文获取它们?如果您可以通过上下文获取它们,则可以将它们注入...如果您唯一的任务是您可以将@Autowire ApplicationContext 放入您的OurAppicationFactoryProvider。不要创建一个新的(在最坏的情况下,您还会遇到类加载器问题并且您多次加载应用程序)。
  • 我会试试的。

标签: spring spring-bean


【解决方案1】:

在基于https://jira.spring.io/browse/SPR-15154 中提到的BeanFactoryLocator/beanRefContext.xml 机制的遗留应用程序中,我添加了一个Singleton 类来创建应用程序上下文并使用该上下文。我的代码是

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public enum SpringContextUtil {
    INSTANCE;
    ApplicationContext context;

    public ApplicationContext getApplicationContext() {
        if (context == null)
            context = new ClassPathXmlApplicationContext("classpath*:beanRefContext.xml");
        return context;
    }

}

我换了

    final BeanFactoryReference ref = ContextSingletonBeanFactoryLocator.getInstance().useBeanFactory(contextKey);
    AbstractApplicationContext context = ((AbstractApplicationContext) ref.getFactory());

AbstractApplicationContext context = (AbstractApplicationContext)SpringContextUtil.INSTANCE.getApplicationContext().getBean(contextKey);

希望这会帮助像我一样的人。

该解决方案可能不适用于所有情况。

【讨论】:

    【解决方案2】:

    在类似的情况下,我们将reintroduced 定位器机制直接放入我们的代码中。

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多