1. 程式人生 > >對Spring IOC容器相關整理(一)

對Spring IOC容器相關整理(一)

1.IOC 控制反轉(Inversion of Control)

控制反轉是一種設計原則,用來降低程式碼之間的耦合性。其中最常見的方式叫做依賴注入(DI)通過控制反轉,物件在被建立的時候,系統內所有物件將通過配置檔案(XML,JavaCode,註解等...)配置的依賴的物件的引用傳遞給它。也可以說,依賴被注入到物件中。

容器(Container)容器的作用就是生成(生命週期開始時)、存放bean的例項並控制每個bean例項的生命週期 ,在適當的時候銷燬bean例項(生命週期結束時)。

Spring框架支援六個作用域,其中四個只有在使用Web感知的ApplicationContext時才可用。也可以建立自定義範圍。

 

作用域

描述

singleton(單例)

(預設)SpringIoC容器為每個bean定義只建立一個物件例項

prototype(原型)

每次呼叫都將建立物件例項。

request(請求)

每次HTTP請求都會建立自己的bean例項。僅僅使用Web感知的ApplicationContext時才可用。

session(會話)

每個會話都會建立自己的bean例項。僅僅使用Web感知的ApplicationContext時才可用。

application(應用)

在ServletContext的生命週期中使用單個bean定義. 僅僅使用Web感知的ApplicationContext時才可用。

Websocket(Websocket)

將單個bean定義作用於WebSocket的生命週期。僅僅使用Web感知的ApplicationContext時才可用。

 

 

IoC模式中,系統通過引入實現了IoC模式的IoC容器,即可由IoC容器來管理物件的生命週期、依賴關係等,從而使得應用程式的配置和依賴性規範與實際的應用程式程式碼分離。其中一個特點就是通過文字的配置檔案進行應用程式元件間相互關係的配置,而不用重新修改並編譯具體的程式碼。

可以把IoC模式看作工廠模式的昇華,把IoC容器看作是一個大工廠,只不過這個大工廠裡要生成的物件都是在配置檔案(XML,JavaCode,註解等...)中給出定義的。利用Java 的“反射”程式設計,根據配置檔案(XML,JavaCode,註解等...)中給出的類定義生成相應的物件。從實現來看,以前在工廠模式裡寫死了的物件,IoC模式改為配置檔案(XML,JavaCode,註解等...),這就把工廠和要生成的物件兩者隔離,極大提高了靈活性和可維護性

1.1、BeanFactory

org.springframework.beans 和org.springframework.context 包是Spring 框架IOC容器的基礎。BeanFactory 介面提供了一種高階配置機制,能夠管理任何型別的物件。ApplicationContext 是BeanFactory的子介面。

BeanFacotry是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory無法支援spring的許多外掛,如AOP功能、Web應用等。 
ApplicationContext介面,它由BeanFactory介面派生而來,ApplicationContext包含BeanFactory的所有功能,通常建議優先使用ApplicationContext

 

 

1 Resource resource = new FileSystemResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);

 

1 ClassPathResource resource = new ClassPathResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);

 

1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
3 BeanFactory factory = (BeanFactory) context;

 

BeanFacotry 提供了六種方法供使用者呼叫

 

  •   boolean containsBean(String beanName) 判斷工廠中是否包含給定名稱的bean定義,若有則返回true
  •   Object getBean(String) 返回給定名稱註冊的bean例項。根據bean的配置情況,如果是singleton模式將返回一個共享例項,否則將返回一個新建的例項,如果沒有找到指定bean,該方法可能會丟擲異常
  •   Object getBean(String, Class) 返回以給定名稱註冊的bean例項,並轉換為給定class型別
  •   Class getType(String name) 返回給定名稱的bean的Class,如果沒有找到指定的bean例項,則丟擲NoSuchBeanDefinitionException異常
  •   boolean isSingleton(String) 判斷給定名稱的bean定義是否為單例模式
  •   String[] getAliases(String name) 返回給定bean名稱的所有別名

參考:Spring BeanFactory與FactoryBean的區別及其各自的詳細介紹於用法

1.2、ApplicationContext

org.springframework.context.ApplicationContext介面表示SpringIoC容器,負責例項化、配置和組裝bean。 BeanFactory 提供了配置框架和基本功能,ApplicationContext 添加了更多特定於企業的功能。ApplicationContext 是一個完整的BeanFactory 的擴充套件集

ApplicationContext 的實現類有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。

ClassPathXmlApplicationContext 預設從類路徑載入配置檔案,FileSystemXmlApplicationContext 預設從檔案系統中裝載配置檔案

和BeanFactory初始化相似,ApplicationContext的初始化也很簡單,如果配置檔案放置在類路徑下,使用者可以優先使用ClassPathXmlApplicationContext實現類:

ApplicationContext ctx = new ClassPathXmlApplicationContext(“com/baobaotao/context/beans.xml”)

對於ClassPathXmlApplicationContext來說,”com/baobaotao/context/beans.xml”等同於”classpath: com/baobaotao/context/beans.xml”。

如果配置檔案放置在檔案系統的路徑下,則可以優先考慮使用FilySystemXmlApplicationContext實現類: 

ApplicationContext ctx =new FileSystemXmlApplicationContext(“com/baobaotao/context/beans.xml”);  

對於FileSystemXmlApplicationContext來說,“com/baobaotao/context/beans.xml”等同於“file:com/baobaotao/context/beans.xml”。

還可以指定一組配置檔案,Spring會自動將多個配置檔案在記憶體中”整合”成一個配置檔案,如下所示:

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{“conf/beans1.xml”,”conf/beans2.xml”});

ApplicationContext的初始化和BeanFactory有一個重大的區別:BeanFactory在初始化容器時,並未例項化Bean,直到第一次訪問某個Bean時才例項目標Bean;而ApplicationContext則在初始化應用上下文時就例項化所有單例項的Bean。因此ApplicationContext的初始化時間會比BeanFactory稍長一些,不過稍後的呼叫則沒有”第一次懲罰”的問題。

 

1.3、WebApplicationContext

WebApplicationContext  繼承了ApplicationContext介面,是ApplicationContext的擴充套件,它增加了WEB應用特性,還可以檢視解析、主題解析、對映,通過ServletContext與servlet關聯 ,WebApplicationContext被繫結在ServletContext上(通過ContextLoaderListener繫結),可以通過RequestContextUtils獲取WebApplicationContext。

WebApplicationContext是專門為web應用準備的,他允許從相對於web根目錄的路勁中裝載配置檔案完成初始化工作,從WebApplicationContext中可以獲得ServletContext的引用,整個Web應用上下文物件將作為屬性放置在ServletContext中,以便web應用可以訪問spring上下文,spring中提供WebApplicationContextUtils的getWebApplicationContext(ServletContext src)方法來獲得WebApplicationContext物件

WebApplicationContext擴充套件了ApplicationContext.在 WebApplicationContext中定義了一個常量 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上下文啟動時,WebApplicationContext以此為鍵放置在ServletContext屬性列表中,

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

ConfigurableWebApplicationContext擴充套件了WebApplicationContext,它允許通過配置的方式例項化,同時設定兩個重要方法

  setServletContext(ServletContext context) 為spring設定web應用上下文,以便兩者整合

setConfigLocations(String[]locations) 設定Spring配置的檔案地址

 

webApplicationContext初始化需要ServletContext,也就是說需要web容器前提下才能·完成啟動工作  可以通過在web.xml中配置自啟動Servlet或Web容器監聽來實現web容器的啟動

Spring分別提供啟動WebApplicationContext的servlet和Web容器監聽器

  org.springframework.web.context.ContextLoaderListener  

 org.springframework.web.context.ContexLoaderServlet     此方法目前以廢棄

 

!--從類路徑下載入Spring配置檔案,classpath特指類路徑下載入-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:smart-context.xml
        </param-value>
    </context-param>
    <!--負責啟動spring容器的監聽器  還可以宣告自啟動的Servlet   ContextLoaderServlet-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

如果使用@Configuration的java類提供配置資訊的配置  web.xml配置修改如下

 

<!--通過指定context引數,讓Spring使用AnnotationConfigWebApplicationContext啟動容器而非XmlWebApplicationContext   預設沒配置時是使用XmlWebApplicationContext-->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
<!--指定標註了@Configuration的類,多個可以用逗號分隔-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.example.Car,com.example.Boss</param-value>
    </context-param>
    <!--監聽器將根據上面的配置使用AnnotationConfigWebApplicationContext
    根據contextConfigLocation
    指定的配置類啟動Spring容器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

參考:WebApplicationContext介紹

1.4 配置元資料

SpringIoC容器使用一種配置元資料。此配置元資料展示了Spring 容器如何在應用程式中例項化、配置和組裝物件。

Spring容器支援基於XML的配置元資料配置,Spring2.5引入了對基於註釋的配置元資料的支援,從Spring3.0開始,Spring JavaConfig 專案提供的許多特性成為核心Spring框架的一部分,引入了對基於Java的配置元資料的支援。

 

基於XML的配置元資料將這些bean配置為在頂層元素<beans/>內部的<bean/>元素。Java配置通常在帶有@Configuration註釋的類中使用帶@Bean註釋的方法。

 

 基於XML的配置元資料的基本結構:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="..." class="..."> ① ②
<!-- collaborators and configuration for this bean go here -->
<!-這個bean的協作者(引用其他的bean)和配置在這裡->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
<!-這個bean的協作者和配置在這裡->
</bean>
<!-- more bean definitions go here -->
<!-更多的bean配置在這裡->
</beans>

<bean>中 id屬性是標識單個bean定義的字串,class屬性定義Bean的型別,並使用完全限定的類名稱。

基於Java的配置元資料的基本結構:

@Configuration  
public class SpringConfig {  
  
    @Bean  
    public Piano piano(){  
        return new Piano();  
    }  
    @Bean(name = "counter")   
    public Counter counter(){  
        return  new Counter(12,"Shake it Off",piano());  
    }  
} 

&n