美文网首页
为啥我不赞成用静态变量存下ApplicationContext

为啥我不赞成用静态变量存下ApplicationContext

作者: dracula337435 | 来源:发表于2019-05-03 01:55 被阅读0次

    有问题的写法

    有些时候想用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

    相关文章

      网友评论

          本文标题:为啥我不赞成用静态变量存下ApplicationContext

          本文链接:https://www.haomeiwen.com/subject/oygpbqtx.html