1. 程式人生 > 實用技巧 >獲取spring容器上下文(webApplicationContext)的幾種方法

獲取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);

  得到的結果是:

  可見這兩個確實不是同一個物件。驗證成功。