Spring--------web应用中保存spring容器

---恢复内容开始---web

问题:在一个web应用中我使用了spring框架,但有一部分模块或组件并无托管给Spring,好比有的多是一个webservice服务类,若是我想在这些非托管的类里使用托管对象该怎么办呢,很天然的咱们须要得到spring容器对象的引用ApplicationContext,个人想法是在服务启动后,想办法将ApplicationContext容器的应用保存到一个静态变量中,之后使用就简单了。spring

1)刚开始用的是spring+struts2,实力话spring用的是ContextLoaderListener,以下缓存

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/comm/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

这种状况下经过写一个listener,在web.xml配置在spring的实例化以后就行,在contextInitialized方法中保存spring容器mvc

 

public class ApplicationContextListener implements ServletContextListener{

    public void contextDestroyed(ServletContextEvent arg0) {
        
    }

    public void contextInitialized(ServletContextEvent event) {
        C.wac = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
        System.out.println("存储spring 容器结束:ApplicationContext="+C.wac);
        
    }
    

}

2)今天写一个新项目,想尝试一下spring mvc,边学边作,第一件事天然是将spring+struts2中的一些东西以spring mvc的方式映射过来,哪不会学哪,天然保存spring容器的引用成为了其中一项映射工做,由于spring mvc的初始化用的是一个servlet(DispatcherServlet),因此不可能再用listener来保存容器(实例化顺序listener -> filter -> servlet),刚开始想的是用servlet,经过配置<load-on-startup>控制servlet的实例化在spring的servlet以后,但不知为何就是没法得到spring容器,一直报空指针异常。最后没办法只能放弃。只能换思路了,在网上找到一个ApplicationContextAware接口,实现该接口的托管对象在被实例化时spring会经过setApplicationContext方法将ApplicationContext对象传入这和struts2中SessionAware等的设计是同样的,测试能够得到spring容器对象的引用,以下(这里有点小知识,spring在启动时对于单例对象会直接实例化,因此配置该对象时不用设置Scope,采用默认便可)app

@Component
public class InitComponent implements  ApplicationContextAware{
    @Override
    public void setApplicationContext(ApplicationContext ac)
            throws BeansException {
        //存储spring容器引用
        C.wac = ac;
    }
}

3)经过实现ApplicationContextAware已能得到容器引用,但有一个问题,若是你但愿在spring容器实例化完作点事,好比启动一个维护线程作点维护工做,该工做可能要用到spring容器里的东东。则上面的方法并不能保证你得到spring容器引用时spring容器已初始化完毕。进一步搜搜搜发现spring提供了一些事件监听框架

spring提供了内置的几类的事件:ContextClosedEvent   、ContextRefreshedEvent(spring实例化完)  、ContextStartedEvent(spring实例化以前)  、ContextStoppedEvent(spring销毁后)   、RequestHandleEventide

 其中的ContextRefreshedEvent正式咱们须要的,在spring容器启动完成后会触发ContextRefreshedEvent事件,监听方法以下,实现测试

ApplicationListener,泛型参数传ContextRefreshedEvent,对于其它事件的监听相似
@Component
public class InitListener implements ApplicationListener<ContextRefreshedEvent>{
@Override
public void onApplicationEvent(ContextRefreshedEvent e) {
  WebApplicationContext wac = (WebApplicationContext)e.getApplicationContext();
  //存储spring容器引用
  C.wac = wac;
  System.out.println(C.wac);
  //存储配置文件路径
  C.CONF_PATH = wac.getServletContext().getRealPath("/WEB-INF/conf");
  System.out.println(C.CONF_PATH);
  //初始化log4j
  PropertyConfigurator.configure(C.CONF_PATH+"/comm/log4j.properties");
  //启动系统缓存
  C.wac.getBean(CacheManager.class).start();
}
}

 

 

---恢复内容结束---spa

相关文章
相关标签/搜索