歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 監聽器如何獲取Spring配置文件

監聽器如何獲取Spring配置文件

日期:2017/3/1 9:13:14   编辑:Linux編程

我們在做項目的時候,會用到監聽器去獲取Spring的配置文件,然後從中拿出我們需要的bean出來,比如做網站首頁,假設商品的後台業務邏輯都做好了,我們需要創建一個監聽器,在項目啟動時將首頁的數據查詢出來放到application裡,即在監聽器裡調用後台商品業務邏輯的方法,也就是說我們需要在監聽器裡獲取Spring中配置的相應的bean。先把監聽器創建出來:

1. 創建InitDataListener

創建一個監聽器InitDataListener繼承ServletContextListener:

/**
 * @Description: TODO(用於項目啟動的時候數據初始化)
 * @author eson_15
 *
 */
//@Component //監聽器是web層的組件,它是tomcat實例化的,不是Spring實例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {
	
	private ProductService productService = null;//productService中定義了跟商品相關的業務邏輯
	
	@Override
	public void contextDestroyed(ServletContextEvent event) {

	}

	@Override
	public void contextInitialized(ServletContextEvent event) {

	}

}

並在web.xml中配置該監聽器:

如上,productService中定義了商品的一些業務邏輯,並且這個productService是交給Spring管理的,那麼我們如何得到這個對象呢?首先肯定的一點是:我們不能自己new出來,因為new出來的話就跟Spring的IoC沒有關系了……主要有三種方式可以實現,我們先一個個分析,最後比較優劣。

2. 直接加載beans.xml文件

這種方式比較簡單粗暴,不是要加載配置文件麼?那好,我加載就是了,如下:

//@Component //監聽器是web層的組件,它是tomcat實例化的,不是Spring實例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {

	
	private ProductService productService = null; //productService中定義了跟商品相關的業務邏輯
	
	@Override
	public void contextDestroyed(ServletContextEvent event) {

	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		// 獲取業務邏輯類productService查詢商品信息		
		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
		productService = (ProductService) context.getBean("productService");
		System.out.println(productService); //輸出看看拿到了沒有		

                //下面是具體productService相關操作……
	}

}

這種方法完全沒問題,思路很清晰,先加載配置文件beans.xml,然後獲取bean,但是啟動tomcat後,我們看看控制台輸出的信息:

到這裡應該發現這種方式的弊端了,加載了兩次配置文件,也就是說那些bean被實例化了兩次,從打印的信息來看,是拿到我們自己加載配置文件是實例化的bean。這種方式明顯不可取。

3. 從ServletContext中獲取

從上面的方法中,我們最起碼可以知道,Spring通過自己的監聽器已經加載過一次配置文件了,我們沒必要再加載一次,那麼很容易想到,如果知道Spring加載後放到哪裡了,那我們就可以從那地方獲取該配置文件,下面我們看下Spring加載配置文件的過程:

上圖中(省略了無關的代碼),ContextLoaderListener就是web.xml中我們配置的Spring監聽器,它也實現了ServletContextListener並繼承了ContextLoader。在監聽器中主要通過initWebApplicationContext方法來獲取配置文件,並創建WebApplicationContext對象,在initWebApplicationContext方法裡主要做兩件事:一是拿到Spring的上下文,二是把Spring上下文放到ServletContext中,並且鍵為:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。那麼如何拿到Spring的上下文呢?是通過獲取web.xml中配置的Spring的路徑,CONFIG_LOCATION_PARM其實是個字符串常量,就是上面web.xml中配置Spring監聽器下面的:

<context-param>
      <param-name>contextConfigLocation</param-name> <!--CONFIG_LOCATION_PARM就是contextConfigLocation-->
      <param-value>classpath:beans.xml</param-value>
</context-param>

所以就很明顯了,通過web.xml中配置的路徑拿到beans.xml,然後加載這個配置文件,實例化bean。

現在我們既然知道了Spring在加載配置文件後,把它放在了ServletContext中,那麼我們就可以去這裡面直接拿!

//@Component //監聽器是web層的組件,它是tomcat實例化的,不是Spring實例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {

	
	private ProductService productService = null;
	
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		// TODO Auto-generated method stub

	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		//  獲取業務邏輯類查詢商品信息
		
		// 解決方案二,項目在啟動時,把Spring配置文件通過Spring的監聽器加載,存儲到ServletContext中,我們只要在ServletContext中獲取即可。
		ApplicationContext context = (ApplicationContext) event.getServletContext()
                                             .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
		productService = (ProductService) context.getBean("productService");
		System.out.println(productService);		
	}

}

這樣我們就可以拿到produceService的實例化對象了,這種方法好是好,就是getAttribute中的參數太長,也不知道當時程序員的腦門子被夾了還是咋地,估計是想不到其他更合適的名字了吧~

4. 通過Spring提供的工具類加載

也許開發Spring的大牛們也意識到了這個參數名字太長了,於是他們提供了一個方法類,可以加載配置文件:

public class InitDataListener implements ServletContextListener {

	
	private ProductService productService = null;
	
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		// TODO Auto-generated method stub

	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		// 獲取業務邏輯類查詢商品信息

		WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
		productService = (ProductService) context.getBean("productService");
		System.out.println(productService);
	}

}

其實,這裡的getWebApplicationContext方法就是把上面的那個方法封裝了一下而已,我們看看這個方法的源碼就知道了:

public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
		return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
	}

這樣更加方便程序員調用,僅此而已……所以一般我們使用第三種方法來獲取Spring的配置文件,從而獲取相應的實例化bean。

Spring中如何配置Hibernate事務 http://www.linuxidc.com/Linux/2013-12/93681.htm

Struts2整合Spring方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm

基於 Spring 設計並實現 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm

Spring-3.2.4 + Quartz-2.2.0集成實例 http://www.linuxidc.com/Linux/2013-10/91524.htm

使用 Spring 進行單元測試 http://www.linuxidc.com/Linux/2013-09/89913.htm

運用Spring注解實現Netty服務器端UDP應用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm

Spring 3.x 企業應用開發實戰 PDF完整高清掃描版+源代碼 http://www.linuxidc.com/Linux/2013-10/91357.htm

Spring 的詳細介紹:請點這裡
Spring 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved