如何在非注入类中,获取spring容器

这两天在修改之前项目中用到的pvuv统计代码 , 遇到了一个问题 , 就是几个项目之间 , 在处理uv的时候 , 都需要特殊的处理 , 区别对待 , 于是我就写了个简单工厂 , 在工厂中初始化不同service的时候 , 想起来平时不用junit测试时 , 就是用的手动读取spring配置的方式来获取容器 , 于是当时想当然地就再次用了这种方法, code如下:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

之后过了一天 , 代码修改完成 , 上测试库测试 , 然后莫名其妙就出现了一个异常 : Dead lock , 而且还是一直不停地死锁 , 仔细检查日志发现是定时任务的问题 , 再一看 , 原来同时有两条线程在跑定时任务 , 这时候我才突然想起来 , 手动加载spring配置文件的话 , 相当于重新加载了一遍所有注入的bean , 于是就有了两个相同的调度在跑了 , 自然就容易出现死锁了 .
于是赶紧去百度google了一把 , 找打了动态获取spring注入的bean , 但是不第二次加载配置的方法 , 方法有好几种 , 比如 :

extends ApplicationObjectSupport 
extends WebApplicationObjectSupport 
implement ApplicationContextAware 

第一种方式 , spring在容器初始化的时候 , 通过方法

void setApplicationContext(ApplicationContext context) 

把容器注入, 然后在需要的时候 , 通过以下方法获取容器对象 .

ApplicationContext getApplicationContext() 

第二种方法与第一种方式类似 , 不同的是返回的容器类型不一样而已 .

其实观察三个类的源码可以发现 , 其实现方式大同小异 , 前两种方式的父类 , 其实也实现了ApplicationContextAware接口 , 再来看一下ApplicationContextAware的注释 :

Interface to be implemented by any object that wishes to be notified of the {@link ApplicationContext} that it runs in.

Implementing this interface makes sense for example when an object requires access to a set of collaborating beans. Note that configuration via bean references is preferable to implementing this interface just for bean lookup purposes 由注释可见 , 这个接口主要就是为了用来获取注入的bean的 . 我使用的是第三种方法 , 写了一个工具类 , 实现了ApplicationContextAware接口 , 专门用来在非注入的类中获取spring容器 .

public class SpringContextFactory implements ApplicationContextAware{
    private static ApplicationContext ctx ;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextFactory.ctx = applicationContext;
    }
    public static ApplicationContext getApplicationInstance(){
        return ctx;
    }
}

然后将 SpringContextFactory 注入在spring的配置文件中即可.

<bean id="springContextFactory" class="com.lrlz.statistical.service.factory.SpringContextFactory">bean>

打包 , 发布 , 死锁的问题终于解决了 , 看来spring框架还是有许多值得我们深掘和学习的地方 , 我还是用得太浅薄了 , 是时候该读一波源码加深理解了 .

你可能感兴趣的:(spring)