1. 程式人生 > >程式碼顯式注入Spring ApplicationContext說明。

程式碼顯式注入Spring ApplicationContext說明。

一、簡單的用ApplicationContext做測試的話,獲得Spring中定義的Bean例項(物件).可以用:

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IRegisterDAO registerDAO = (IRegisterDAO)ac.getBean("RegisterDAO");

如果是兩個以上:
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml","dao.xml"});

或者用萬用字元:
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/*.xml");

二、ClassPathXmlApplicationContext[只能讀放在web-info/classes目錄下的配置檔案]和FileSystemXmlApplicationContext的區別

classpath:字首是不需要的,預設就是指專案的classpath路徑下面;
如果要使用絕對路徑,需要加上file:字首表示這是絕對路徑;

對於FileSystemXmlApplicationContext:
預設表示的是兩種:

1.沒有碟符的是專案工作路徑,即專案的根目錄;
2.有碟符表示的是檔案絕對路徑.

// 用classpath路徑
ApplicationContext factory = new ClassPathXmlApplicationContext("classpath:appcontext.xml");
ApplicationContext factory = new ClassPathXmlApplicationContext("appcontext.xml");

ClassPathXmlApplicationContext使用了file字首是可以使用絕對路徑的
ApplicationContext factory = new ClassPathXmlApplicationContext("file:F:/workspace/example/src/appcontext.xml");

// 用檔案系統的路徑,預設指專案的根路徑
ApplicationContext factory = new FileSystemXmlApplicationContext("src/appcontext.xml");
ApplicationContext factory = new FileSystemXmlApplicationContext("webRoot/WEB-INF/appcontext.xml");

// 使用了classpath:字首,這樣,FileSystemXmlApplicationContext也能夠讀取classpath下的相對路徑
ApplicationContext factory = new FileSystemXmlApplicationContext("classpath:appcontext.xml");
ApplicationContext factory = new FileSystemXmlApplicationContext("file:F:/workspace/example/src/appcontext.xml");

// 不加file字首
ApplicationContext factory = new FileSystemXmlApplicationContext("F:/workspace/example/src/appcontext.xml");

需求的提出:

我們知道如果我們要在一個類使用spring提供的bean物件,我們需要把這個類注入到spring容器中,交給spring容器進行管理,但是在實際當中,我們往往會碰到在一個普通的Java類中,想直接使用spring提供的其他物件或者說有一些不需要交給spring管理,但是需要用到spring裡的一些物件。如果這是spring框架的獨立應用程式,我們通過

ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId"); 

這樣的方式就可以很輕易的獲取我們所需要的物件。

但是往往我們所做的都是Web Application,這時我們啟動spring容器是通過在web.xml檔案中配置,這樣就不適合使用上面的方式在普通類去獲取物件了,因為這樣做就相當於載入了兩次spring容器,而我們想是否可以通過在啟動web伺服器的時候,就把Application放在某一個類中,我們通過這個類在獲取,這樣就可以在普通類獲取spring bean物件了,讓我們接著往下看。

1. 通過Spring提供的工具類獲取ApplicationContext物件這種方式不需要修改任何的配置,只需要在你需要的地方,當然要求也比較高,需要能夠獲取HttpServletRequest物件,比如在jsp程式碼中使用,程式碼如下:

<%
  /**
    上面兩個工具方式的區別是,前者在獲取失敗時丟擲異常,後者返回null。
  */
  ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext()); 
  ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()); 
  MyService service1 = (MyService)ac1.getBean("myService");//這是beanId. 
  MyService service2 = (MyService)ac2.getBean("myService");
  out.println("第一種方式1----:"+service1.getSystemTime());//獲取系統時間
  out.println("<br />------------<br />");
  out.println("第一種方式2----:"+service2.getSystemTime());
%>

注:程式碼直接複製是不能正常執行的,需要需要bean的名稱.

這種方式明顯有很大的漏洞,感覺用起來不舒服,其一:需要request物件,其他很難封裝一個Java工具類。

2. 繼承自抽象類ApplicationObjectSupport 

我們編寫一個當啟動web服務容器的時候,就將ApplicationContext注入到一個spring工具類的一個靜態屬性中,這樣在普通類就可以通過這個工具類獲取ApplicationContext,從而通過getBean( )獲取bean物件。

我們把這個工具類取名為:ToolSpring放在net.angel.tools包下:

程式碼如下:

package net.angel.tools;
import javax.faces.application.Application;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.web.context.support.WebApplicationObjectSupport;
/**
 * 獲取spring資訊的工具類
 * @author Administrator
 *
 */
public final class ToolSpring extends ApplicationObjectSupport {
  private static ApplicationContext applicationContext = null;
  @Override
  protected void initApplicationContext(ApplicationContext context)
  throws BeansException {
    super.initApplicationContext(context);
    if(ToolSpring.applicationContext == null){
      ToolSpring.applicationContext = context;
      System.out.println();
      System.out.println();
      System.out.println("---------------------------------------------------------------------");
      System.out.println("========ApplicationContext配置成功,在普通類可以通過呼叫ToolSpring.getAppContext()獲取applicationContext物件,applic      ationContext="+applicationContext+"========");
      System.out.println("---------------------------------------------------------------------");
      System.out.println();
      System.out.println();
    }
  }
  public static ApplicationContext getAppContext() {
    return applicationContext;
  }
  public static Object getBean(String name){
    return getAppContext().getBean(name);
  }
}

編寫完程式碼之後,我們需要在spring配置檔案中加入:

<!-- 這個主要是用於普通類呼叫spring物件的配置,可以不配置id屬性. -->
<bean id="toolSpring" class="net.angel.tools.ToolSpring"></bean>

這個配置,這步很重要,前往不能忘了,如果沒有配置的話,獲取的ApplicationContext將為null。

這樣在啟動的時候就會載入這個類,如果成功的話,會在控制檯看到System.out.println的輸出資訊。

在普通類可以通過ToolSpring.getBean("beanId");獲取spring的bean物件。

3. 繼承自抽象類WebApplicationObjectSupport 

這種方式和第二種差不多,不過多介紹,直接給程式碼:

package net.angel.tools;
import javax.faces.application.Application;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.web.context.support.WebApplicationObjectSupport;
/**
 * 獲取spring資訊的工具類
 * @author Administrator
 *
 */
public final class ToolSpring extends WebApplicationObjectSupport{
  private static ApplicationContext applicationContext = null;
  @Override
  protected void initApplicationContext(ApplicationContext context) {
    super.initApplicationContext(context);
    if(applicationContext == null){
      applicationContext = context;
      System.out.println();
      System.out.println();
      System.out.println("---------------------------------------------------------------------");
      System.out.println("========ApplicationContext配置成功,在普通類可以通過呼叫ToolSpring.getAppContext()獲取applicationContext物件,applicationContext="+applicationContext+"========");
      System.out.println("---------------------------------------------------------------------");
      System.out.println();
      System.out.println();
    }
  }
  public static ApplicationContext getAppContext() {
    return applicationContext;
  }
  public static Object getBean(String name){
    return applicationContext.getBean(name);
  }
}

Spring配置檔案加入:

<!-- 這個主要是用於普通類呼叫spring物件的配置,可以不配置id屬性. -->
<bean id="toolSpring" class="net.angel.tools.ToolSpring"></bean>

4. 實現介面ApplicationContextAware

這種方式是實現介面的方式,本人比較喜歡這種方式,因為這種方式擴充套件性比較強,我們可以根據需要在加入其他的介面。方式跟以上幾種方式差不多。

package net.angel.tools;
import javax.faces.application.Application;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.web.context.support.WebApplicationObjectSupport;
/**
 * 獲取spring資訊的工具類
 * @author Administrator
 *
 */
public final class ToolSpring implements ApplicationContextAware{
  private static ApplicationContext applicationContext = null;
  @Override
  public  void setApplicationContext(ApplicationContext applicationContext)
  throws BeansException {
    if(ToolSpring.applicationContext == null){
      ToolSpring.applicationContext  = applicationContext;
      System.out.println();
      System.out.println();
      System.out.println("---------------------------------------------------------------------");
      System.out.println("========ApplicationContext配置成功,在普通類可以通過呼叫ToolSpring.getAppContext()獲取applicationContext物件,appl      icationContext="+applicationContext+"========");
      System.out.println("---------------------------------------------------------------------");
      System.out.println();
      System.out.println();
    }
  }
  public static ApplicationContext getApplicationContext() {
    return applicationContext;
  }
  public static Object getBean(String name){
    return getApplicationContext().getBean(name);
  }
}

在Spring配置檔案中加入:

<!-- 這個主要是用於普通類呼叫spring物件的配置,可以不配置id屬性. -->
<bean id="toolSpring" class="net.angel.tools.ToolSpring"></bean>

在其他類通過使用

ToolSpring.getBean("beanId");就可以進行呼叫了。