有没有一种在Spring应用程序中静态/全局请求ApplicationContext副本的方法?
假设主类启动并初始化应用程序上下文,是否需要将其通过调用堆栈传递到需要它的任何类中,还是有一种方法可供类请求先前创建的上下文? (我认为必须是单例模式?)
有没有一种在Spring应用程序中静态/全局请求ApplicationContext副本的方法?
假设主类启动并初始化应用程序上下文,是否需要将其通过调用堆栈传递到需要它的任何类中,还是有一种方法可供类请求先前创建的上下文? (我认为必须是单例模式?)
您可以实现ApplicationContextAware
接口,也可以直接使用@Autowired
注解:
public class SpringBean {
@Autowired
private ApplicationContext appContext;
}
SpringBean
将会注入 ApplicationContext
,在其中实例化该bean。例如,如果您有一个带有相当标准的上下文层次结构的Web应用程序:
main application context <- (child) MVC context
如果SpringBean
在主要上下文中声明,它将注入到主要上下文中;
否则,如果它在MVC上下文中声明,它将被注入到MVC上下文中。
@Inject
。 - Alireza Fattahi这里有一个不错的方法(非本人所创,原始参考链接在此:http://sujitpal.blogspot.com/2007/03/accessing-spring-beans-from-legacy-code.html)。
我使用过这种方法,并且它很有效。基本上,这是一个简单的 bean,它包含一个(静态)应用程序上下文引用。通过在 spring 配置中引用它,就可以初始化它。
请参考原始链接,它非常清晰易懂。
getBean
,那么这种方法可能会失败,因为在请求之前Spring上下文不会设置。这是一个竞争条件,今天我刚刚碰到它,尽管在成功使用此方法2年后。 - Dave我相信你可以使用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团队不鼓励使用这个类,等等,但在我使用它的地方,它很适合我。
SpringApplicationContext.java
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* Wrapper to always return a reference to the Spring Application
Context from
* within non-Spring enabled beans. Unlike Spring MVC's
WebApplicationContextUtils
* we do not need a reference to the Servlet context for this. All we need is
* for this bean to be initialized during application startup.
*/
public class SpringApplicationContext implements
ApplicationContextAware {
private static ApplicationContext CONTEXT;
/**
* This method is called from within the ApplicationContext once it is
* done starting up, it will stick a reference to itself into this bean.
* @param context a reference to the ApplicationContext.
*/
public void setApplicationContext(ApplicationContext context) throws BeansException {
CONTEXT = context;
}
/**
* This is about the same as context.getBean("beanName"), except it has its
* own static handle to the Spring context, so calling this method statically
* will give access to the beans by name in the Spring application context.
* As in the context.getBean("beanName") call, the caller must cast to the
* appropriate target class. If the bean does not exist, then a Runtime error
* will be thrown.
* @param beanName the name of the bean to get.
* @return an Object reference to the named bean.
*/
public static Object getBean(String beanName) {
return CONTEXT.getBean(beanName);
}
}
来源: http://sujitpal.blogspot.de/2007/03/accessing-spring-beans-from-legacy-code.html
这篇文章介绍了如何从遗留代码中访问Spring框架的Bean。我们可以通过将Spring应用程序上下文初始化为一个静态成员变量来实现这一点。然后,在需要访问Spring Bean的类中,我们只需要使用该静态成员变量即可访问Bean。要访问Bean,我们还必须调用getBean方法,并指定要访问的Bean的名称。由于在Spring配置文件中将Bean定义为单例,因此我们可以始终获得相同的Bean实例。在Spring应用程序中,有很多种方法可以获取应用程序上下文,以下是一些方法:
Via ApplicationContextAware:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class AppContextProvider implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
这里的setApplicationContext(ApplicationContext applicationContext)
方法将会获取到应用程序上下文。
ApplicationContextAware:
任何希望被通知其运行的ApplicationContext的对象都需要实现此接口。例如,当一个对象需要访问一组协作的bean时,实现此接口是有意义的。
Via Autowired:
@Autowired
private ApplicationContext applicationContext;
这里的@Autowired
关键字将提供applicationContext。Autowired关键字存在一些问题。它在单元测试期间可能会出现问题。
@ContextConfiguration({"classpath:foo.xml"})
@ContextConfiguration({"classpath:foo.xml", "classpath:bar.xml})
@ContextConfiguration({"classpath:foo.xml"})
请看 ContextSingletonBeanFactoryLocator。它提供了静态访问器,用于获取Spring上下文(假设以某种方式注册)。
虽然不太美观,比您想象的更加复杂,但确实有效。
instance()
方法作为工厂,@Antonin,那可能会起作用。然而,我认为我刚刚让所有代码在容器外部首先访问容器。然后该代码可以从容器请求对象。 - Don Kirkby