问题
在程序中为了使用已被实例化的bean,会用到这样的代码:
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext-common.xml");
AbcService abcService = (AbcService)appContext.getBean("abcService");
但是这样会重新装载applicationContext-common.xml并实例化上下文bean,如果有些线程类也是在这个配置文件中,那么造成做相同工作的线程被实例化了两次.一次是bean启动时,一次是上述代码实例化了一次.相当于重新初始化了一遍,这样就产生了冗余.
解决办法
不用类似new ClassPathXmlApplicationContext的方式,从已有的spring上下文取得已实例化的bean.通过ApplicationContextAware接口进行实现.
用一个类实现ApplicationContextAware接口,可以获得ApplicationContext中所有的bean.换句话说就是这个类可以直接获取spring配置文件中所有有引用到的bean对象
ApplicationContextAware怎么用
- 方法类AppUtil实现ApplicationContextAware接口
@Component
public class AppUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
applicationContext = arg0;
}
public static Object getObject(String id) {
Object object = null;
object = applicationContext.getBean(id);
return object;
}
}
[备注] (1) 在spring配置文件中,注册方法类AppUtil.之所以类AppUtil能够灵活自如的获取ApplicationContext,就是因为spring能够自动地执行setApplicationContext. 但是,spring不会无缘无故的为某个类执行他的方法,所以,就需要通过注册方法类Util的方式告知spring有这样一个子类的存在.这里使用的Component进行注册,或者可以在配置文件声明bean:
<bean id="appUtil" class="com.htsoft.core.util.AppUtil"/>
(2)加载Spring配置文件时,如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware接口中的setApplicationContext
public void setApplicationContext(ApplicationContext context) throws BeansException
方法,获得ApplicationContext对象,Application对象是由spring注入的.前提必须在Spring配置文件中指定该类.
(3)使用静态的成员ApplicationContext类型的对象
使用场景备注
从ApplicationContextAware获取ApplicationContext上下文的情况,仅适用于当前运行的代码和已启动Spring处于同一个Spring上下文,否则获取到的ApplicationContext是空的
原文作者连接:www.jianshu.com/p/4c0723615…