为啥我不赞成用静态变量存下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被调用多次,参数为不同的ApplicationContextstatic变量保存的引用和期待的就不一样。
通常我们不会写出多个ApplicationContext,但是,spring-webmvc就这么干了,在一个jvm中启动了多个ApplicationContext,而且他们之间还有父子关系,详见笔者另一篇博文《spring-webmvc应用中有几个ApplicationContext》
从另一个角度讲,笔者一直理解ApplicationContext在jvm中圈出了一个隔离起来的空间,应避免static属性这样的全局用法。

应该怎么办

如果是为了得到ApplicationContext,可以

  1. 让用的类实现ApplicationContextAware,通过实现setter方法得到
  2. @Autowired一个ApplicationContext,可用于属性、构造器或setter方法上

实际观察后,发现用这个工具类多是为了getBean(...),其实完全可以通过其他途径做到,比如@Autowired,可用于属性,构造器或setter方法上。
比较棘手的是需要小scope的bean时,应该使用其他方式,比如:

  1. xml中使用<aop:scope-proxy>
  2. xml中使用<beans:lookup-method>@Configuration类中@Lookup
上一篇下一篇

猜你喜欢

热点阅读