1. 程式人生 > >4. Spring:配置檔案淺析

4. Spring:配置檔案淺析

4. Spring:配置檔案淺析

  1. 概述

    Spring 的配置檔案是用於指導 Spring 工廠進行 Bean 的生產、依賴關係注入及 Bean 例項分發的"圖紙”,它是一個或多個標準的XML文件

    • 配置檔案示例

      <beans>
          <import  resource="resource1.xml” />   (載入多個配置檔案)
          <import  resource="resource2.xml” />
          <bean id="bean1” class="***”></bean>
          <bean name="bean2” class="***”></
      bean
      >
      <alias alias="bean3” name="bean2” /> (別名) </beans>
    • Spring高層檢視

      • Spring容器啟動基本條件
        • Spring框架包
        • Bean配置資訊
        • Bean實現類
      • Bean的元資料資訊
        • 實現類
        • 屬性資訊
        • 依賴關係
        • 行為配置
        • 建立方式

      在這裡插入圖片描述

    • 基於XML的配置

  2. Bean的命名(示例 note_4/definition )

    • Bean id的命名方式

      Bean可以有一個或多個id,第一個id稱為"識別符號”,其餘叫做別名

      • 示例1 配置全限定類名,唯一
      • 示例2 指定id,唯一
      • 示例3 指定name,唯一
      • 示例4 同時指定id和name
      • 示例5 指定多個name
      • 示例6 指定別名 唯一
    • 為什麼id和name共存

      id是唯一的,可以解析xml判斷是否存在

      name在執行時才可以判斷是否存在

    • 命名約定

      • 遵循xml命名規範
      • 字母數字下劃線
      • 駝峰式
  3. Bean的例項化

    • 比較

      • 傳統方法:new和反射
      • Spring IoC:配置元資料使用反射機制
    • IoC建立例項的方式

      • 使用構造器例項化Bean:預設構造器和有引數構造器
      • 使用靜態工廠方法例項化Bean:制定必需的class和factoryMethod,允許指定方法引數
      • 使用例項工廠方法例項化Bean:不能指定class屬性,必須使用factoryBean指定工廠Bean,factoryMethod指定例項化Bean的方法
    • 具體示例(note_4/instance)

      • 構造器例項化

        構造器例項化 Bean 是最簡單的方式,Spring IoC容器既能使用預設空構造器也能使用有引數構造器兩種方式建立Bean,如以下方式指定要建立的Bean型別

        1. 空構造器例項化:
        <bean id="helloServiceNoWithArgs" class="com.***.HelloWorldImpl" />
        
        2. 有引數構造器例項化:
        <bean id="helloServiceWithArgs" class=" com.***.HelloWorldmpl">
            <!-- 指定構造器引數 -->  
            <constructor-arg index="0" value="Hello Spring!"/>  
        </bean>
        
        
      • 靜態工廠例項化

        使用靜態工廠的方式除了指定必須的class屬性,還要指定factory-method屬性來指定例項化Bean的方法,而且使用靜態工廠方法也允許指定方法引數,Spring IoC容器將呼叫此屬性指定的方法來獲取Bean,配置如下:

        <!--使用有引數構造引數-->  
        <bean id="helloServiceStaticFactory" class="com.***.HelloWorldStaticFactory" factory-method="newInstance">
                  <!-- 指定構造器引數 -->  
                 <constructor-arg index="0" value="Hello Static Factory!"/>  
        </bean>
        
        
      • 例項工廠例項化

        使用例項工廠方式不能指定class屬性,此時必須使用factory-bean屬性來指定工廠Bean,factory-method屬性指定例項化Bean的方法,而且使用例項工廠方法允許指定方法引數,方式和使用構造器方式一樣,配置如下:

         <!-- 1、定義例項工廠Bean -->
        <bean id="beanInstanceFactory" class="note_4.instance.HelloWorldInstanceFactory" />
            <!-- 2、使用例項工廠Bean建立Bean -->
           <bean id="helloWorldInstance" factory-bean="beanInstanceFactory"  factory-method="newInstance">
               <constructor-arg index="0" value="Hello Instance Factory!"></constructor-arg>
           </bean>
        </beans>
        
        
  4. Bean的作用域

    Spring Bean 中所說的作用域,在配置檔案中即是"scope”。在面向物件程式設計中一般指物件或變數之間的可見範圍。而在Spring容器中是指其建立的Bean物件相對於其他Bean物件的請求可見範圍

    • 作用域的型別與配置

      在Spring 容器當中,一共提供了5種作用域型別,在配置檔案中,通過屬性scope來設定bean的作用域範圍。

      singleton,只會存在一個共享的bean例項,儲存在單例快取中
      <bean id="userInfo" class="com.UserInfo" scope="singleton"></bean>
      
      prototype:有狀態的bean使用prototype,每次請求該bean,都會建立一個新的
      <bean id="userInfo" class="com.UserInfo" scope=" prototype "></bean>
      
      request:針對每一次的http請求,根據該bean定義建立全新的例項,僅在當前http請求範圍內有效
      <bean id="userInfo" class="com.UserInfo" scope=" request "></bean>
      
      session:類似request
      <bean id="userInfo" class="com.UserInfo" scope=" session "></bean>
      
      global session:
      <bean id="userInfo" class="com.UserInfo"    scope="globalSession"></bean>
      
      
      • singleton

        singleton作用域是指在Spring IoC容器中僅存在一個Bean的示例,Bean以單例項的方式存在,單例項模式是重要的設計模式之一,在Spring中對此實現了超越,可以對那些非執行緒安全的物件採用單例項模式

        singleton的配置方式:
        1. <bean id="car" class="com.Car" scope="singleton"></bean>
        2. <bean id="boss1" class="com.Boss" p:car-ref="car"></bean>(引用了car)
        3. <bean id="boss2" class="com.Boss" p:car-ref="car"></bean>(引用了car)
        4. <bean id="boss3" class="com.Boss" p:car-ref="car"></bean>(引用了car) 
        

        (快取的形式存在,會提前例項化,方便提前發現問題,同時因為被快取,多次使用的時候節約時間)

        在這裡插入圖片描述

      • prototype

        prototype作用域是指每次從容器中呼叫Bean時,都返回一個新的例項,即每次呼叫getBean()時,相當於執行new Bean()的操作。在預設情況下,Spring容器在啟動時不例項化prototype的Bean:

        prototype的配置方式:
        1. <bean id="car" class="com.Car" scope="prototype"></bean>
        2. <bean id="boss1" class="com.Boss" p:car-ref="car"></bean>
        3. <bean id="boss2" class="com.Boss" p:car-ref="car"></bean>
        4. <bean id="boss3" class="com.Boss" p:car-ref="car"></bean>
        
        

        在這裡插入圖片描述

      • request,session和globalSession

        當用戶使用Spring的WebApplicationContext時,還可以使用另外3種Bean的作用域,即request,session和globalSession。在使用Web應用環境相關的Bean作用域時,必須在Web容器中進行一些額外的配置:

        低版本Web容器配置:
        <filter>  
            <filter-name>requestContextFilter</filter-name>  
            <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>  
        </filter>  
        <filter-mapping>  
            <filter-name>requestContextFilter</filter-name>  
            <servlet-name>/*</servlet-name>  
        </filter-mapping> 
        高版本Web容器配置:
        <listener> <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class></listener>
        
      • 例項(note_4/scope)

      • 自定義作用域

        在Spring 2.0中,Spring的Bean作用域機制是可以擴充套件的,這意味著,你不僅可以使用Spring提供的預定義Bean作用域,還可以定義自己的作用域,甚至重新定義現有的作用域(不提倡這麼做,而且你不能覆蓋內建的singleton和prototype作用域)

        //實現自定義Scope類: 
        org.springframework.beans.factory.config.Scope
        //註冊自定義Scope類: 
        ConfigurableBeanFactory.registerScope(String scopeName, Scope scope)
        //使用自定義的Scope: 
        Scope customScope = new ThreadScope();
        beanFactory.registerScope(“thread”, customeScope);
        <bean id="***" class="***"  scope=“scopeName” />
        
  5. 配置檔案的整合

    • 當存在多個配置檔案時

      • Spring-Common.xml位於common資料夾下
      • Spring-Connection.xml位於connection資料夾下
      • Spring-Module.xml位於module資料夾下
    • 傳統載入方法

      ApplicationContext context = new ClassPathXmlApplicationContext(new String[] 
          {"Spring-Common.xml","Spring-Connection.xml","Spring-ModuleA.xml"});
      
      
    • 整合配置檔案:Spring-All-Module.xml

      <beans .....>
      
          <importresource="common/Spring-Common.xml"/>
      
          <importresource="connection/Spring-Connection.xml"/>
      
          <import resource="module/Spring-Module.xml"/>
      
      </beans>
      
      
    • 整合後加載

      ApplicationContext context = new ClassPathXmlApplicationContext(“Spring-All-Module.xml”);