为啥我不赞成用静态变量存下ApplicationContext
2019-05-03 本文已影响0人
dracula337435
有问题的写法
有些时候想用ApplicationContext
又怕麻烦,于是使用一个工具类持有当前的ApplicationContext
,保存为静态变量,代码示例如下:
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
}
使用时代码如下:
ApplicationContextHolder.getApplicationContext().getBean("略")
static
的本意是方便工具类使用,不需要实例。
问题出在哪
static
意味着独一个,如果这个bean被声明在同一个jvm
的多个ApplicationContext
中,问题就出现了。
setter
被调用多次,参数为不同的ApplicationContext
,static
变量保存的引用和期待的就不一样。
通常我们不会写出多个ApplicationContext
,但是,spring-webmvc
就这么干了,在一个jvm中启动了多个ApplicationContext,而且他们之间还有父子关系,详见笔者另一篇博文《spring-webmvc应用中有几个ApplicationContext》。
从另一个角度讲,笔者一直理解ApplicationContext在jvm中圈出了一个隔离起来的空间,应避免static属性这样的全局用法。
应该怎么办
如果是为了得到ApplicationContext
,可以
- 让用的类实现
ApplicationContextAware
,通过实现setter
方法得到 -
@Autowired
一个ApplicationContext
,可用于属性、构造器或setter
方法上
实际观察后,发现用这个工具类多是为了getBean(...)
,其实完全可以通过其他途径做到,比如@Autowired
,可用于属性,构造器或setter
方法上。
比较棘手的是需要小scope
的bean时,应该使用其他方式,比如:
-
xml
中使用<aop:scope-proxy>
-
xml
中使用<beans:lookup-method>
或@Configuration
类中@Lookup