是否有一种方法可以在Spring应用程序中静态/全局地请求ApplicationContext的副本?
假设主类启动并初始化了应用程序上下文,它是否需要通过调用堆栈向下传递给任何需要它的类,或者类是否有一种方法来请求先前创建的上下文?(我假设它必须是单例的?)
是否有一种方法可以在Spring应用程序中静态/全局地请求ApplicationContext的副本?
假设主类启动并初始化了应用程序上下文,它是否需要通过调用堆栈向下传递给任何需要它的类,或者类是否有一种方法来请求先前创建的上下文?(我假设它必须是单例的?)
当前回答
这里有一个很好的方法(不是我的,原始参考在这里: http://sujitpal.blogspot.com/2007/03/accessing-spring-beans-from-legacy-code.html
我使用过这种方法,效果很好。基本上,它是一个简单的bean,包含对应用程序上下文的(静态)引用。通过在spring配置中引用它来初始化它。
看看原来的裁判,非常清楚。
其他回答
我相信你可以使用SingletonBeanFactoryLocator。beanRefFactory.xml文件将保存实际的applicationContext,它将像这样:
<bean id="mainContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>../applicationContext.xml</value>
</list>
</constructor-arg>
</bean>
从应用上下文中获取bean的代码是这样的:
BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
BeanFactoryReference bf = bfl.useBeanFactory("mainContext");
SomeService someService = (SomeService) bf.getFactory().getBean("someService");
Spring团队不鼓励使用这个类和yadayada,但它很适合我使用它的地方。
你可以实现ApplicationContextAware或者使用@Autowired:
public class SpringBean {
@Autowired
private ApplicationContext appContext;
}
SpringBean将注入ApplicationContext,在其中实例化此bean。例如,如果你有一个非常标准的上下文层次结构的web应用程序:
main application context <- (child) MVC context
并且SpringBean是在主上下文中声明的,它将被注入主上下文; 否则,如果它是在MVC上下文中声明的,它将被注入MVC上下文。
在你执行任何其他建议之前,问自己这些问题…
为什么我要获取ApplicationContext? 我是否有效地使用ApplicationContext作为服务定位器? 我可以完全避免访问ApplicationContext吗?
在某些类型的应用程序(例如Web应用程序)中,这些问题的答案比在其他应用程序中更容易,但无论如何都值得一问。
访问ApplicationContext确实违反了整个依赖注入原则,但有时您没有太多选择。
请注意;下面的代码将创建新的应用程序上下文,而不是使用已经加载的上下文。
private static final ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
还要注意,beans.xml应该是src/main/resources的一部分,这意味着在war中它是WEB_INF/classes的一部分,其中真正的应用程序将通过Web.xml中提到的applicationContext.xml加载。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>META-INF/spring/applicationContext.xml</param-value>
</context-param>
在ClassPathXmlApplicationContext构造函数中很难提及applicationContext.xml路径。ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml")无法定位文件。
因此,最好通过使用注释来使用现有的applicationContext。
@Component
public class OperatorRequestHandlerFactory {
public static ApplicationContext context;
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
context = applicationContext;
}
}
方法1:您可以通过实现ApplicationContextAware接口来注入ApplicationContext。参考链接。
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private ApplicationContext applicationContext;
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
方法2:在任何spring托管bean中自动装配应用程序上下文。
@Component
public class SpringBean {
@Autowired
private ApplicationContext appContext;
}
参考链接。