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

相關文章
相關標籤/搜索