獲取spring容器上下文(webApplicationContext)的幾種方法
在很多情況,我們需要先獲取spring容器上下文,即webApplicationContext,然後通過webApplicationContext來獲取其中的bean。典型的情況是,我想在一個並未委託給spring容器管理的物件裡,去引用一個spring容器管理的物件,此時,@Resource註解是無法發揮作用的。此時必須使用webApplicationContext.getBean("beanName")才能從容器中取到這個java物件,不然我們就只能自己去new了。
方法1::ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
經驗證是可行的,但是有個問題,就是執行這句程式碼的時候很耗時。本人猜測這句程式碼會重新new一個容器物件,相當於重新載入了一次applicationContext.xml裡面配置的類,重新去create一個ApplicationContext,而不是去拿在專案啟動之初生成的那個ApplicationContext。
方法2.首先建立一個工具類
package com.wonyen.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class MySpringContext implements ApplicationContextAware {
private static ApplicationContext context;//宣告一個靜態變數用於儲存spring容器上下文
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
this.context=context;
}
public static ApplicationContext getContext(){
return context;
}
}
1.可見該工具類實現了ApplicationContextAware介面,實現該介面的類會接收到spring容器傳過來的ApplicationContext物件,從而可以實現操縱spring容器中的所有bean的效果。但是這裡我們並不在這個工具類裡面去獲取bean,我們暫且把獲取來的ApplicationContext物件存放起來,放在哪裡呢,就是放在該類的一個靜態變數中context中,然後我們再給它一個靜態的get方法,供其他的類去呼叫。
2.有了這個工具類還沒用,spring容器不會無緣無故去執行setApplicationContext方法把ApplicationContext 物件傳入給它,所以必須在ApplicationContext.xml檔案裡面去配置,如下所示。
<!-- util -->
<bean class="com.wonyen.util.MySpringContext"></bean>
這樣,當專案啟動時,就會載入這個工具類,並把ApplicationContext 傳入。當然你也可以採用註解的方式,即在該類上加上@Component註解。
3.在其他類呼叫,只需要這樣一行程式碼就可以了。
ApplicationContext context =MySpringContext.getContext();
經驗證,採用這種方式獲取的ApplicationContext的速度明顯比前面那種快很多。
方法3:還有一種方法可以獲取ApplicationContext,就是傳入一個ServletContext物件。然後用WebApplicationContextUtils的getWebApplicationContext獲取一個WebApplicationContext,WebApplicationContext是ApplicationContext的子類,他比ApplicationContext類多了一個獲取ServletContext的方法。
ServletContext servletContext = event.getServletContext();
ApplicationContext application = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
其實上述方法能獲取到WebApplicationContext時因為web專案在啟動的時候,在啟動spring容器的時候,把WebApplicationContext作為一個屬性放入了ServletContext中,所以我們才可以採用spring提供的這個方法來獲取到WebApplicationContext。
方法4:因為WebApplicationContext是ApplicationContext的子類,所以獲取到WebApplicationContext其實就是獲取到了ApplicationContext。所以還有一種更為簡單的方法,直接通過ContextLoader的靜態方法getCurrentWebApplicationContext()就可以獲取到當前的WebApplicationContext物件.
程式碼如下:
WebApplicationContext webApplicationContext = ContextLoader
.getCurrentWebApplicationContext();
PSSS:關於第一種方法和後面三種方法,為了驗證猜想,即採用new ClassPathXmlApplicationContext("applicationContext.xml");這種方法會重新生成一個ApplicationContext物件,做了如下程式碼的驗證。
ApplicationContext context = MySpringContext.getContext();
ApplicationContext newContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
System.out.println("獲取已有的ApplicationContext物件" + context);
System.out.println("新建的ApplicationContext" + newContext);
得到的結果是:
可見這兩個確實不是同一個物件。驗證成功。