1. 程式人生 > >Spring 學習歷程(三)

Spring 學習歷程(三)

Bean容器初始化

  • 基礎
    • org.springframework.beans
    • org.springframework.context
    • BeanFactory提供配置結構和基本功能,載入並初始化Bean
    • ApplicationContext儲存了Bean物件,並且在Spring進行使用
  • ApplicationContext範圍
    • 載入本地檔案
      FileSystemXmlApplication context = new FileSystemXmlApplicationContext("F://test//context.xml");
    • 載入ClassPath檔案
      ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*/resources/context.xml");
    • web應用配置檔案
  • Spring注入方式
    • 定義:Spring注入是指啟動Spring容器啟動並載入Bean的過程中,完成對變數的賦值行為
    • 注入方式:
      • 設值注入:是將變數以Set屬性的方式注入到Bean中,使用設定注入,在Bean中一定要有變數的Set方法,配置中的<property>標籤name的值一定要Set方法中的引數名稱一致!!!
        <?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 http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id="InjectionServiceImpl" class="com.jing.spring.bean.InjectionServiceImpl"> <property name="injectionDao" ref="injectionDao"></property> </bean> <bean id="injectionDao" class
        ="com.jing.spring.bean.InjectionDaoImpl"></bean><!--??????不懂 程式中是引用介面 為什麼卻要把實現類注入?--> </beans>
        private InjectionDao injectionDaoss;
        
            public void setInjectionDao(InjectionDao injectionDao) {
                this.injectionDaoss = injectionDao;
            }
        
            public void save(String arg) {
                System.out.print("InjectionServiceImpl中的arg==="+arg+"\n");
                //邏輯處理
                arg=arg+":"+this.hashCode();
                injectionDaoss.save(arg);
            }
      • 構造注入:是將變數作為Bean構造器的引數傳入,在Bean中一個要有一個以變數作為引數的建構函式,配置中的<constructor-arg>標籤name的值一定要和有參構造方法引數名稱一致!!!
        <?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
                http://www.springframework.org/schema/beans/spring-beans.xsd" >
        
                <bean id="InjectionServiceImpl" class="com.jing.spring.bean.InjectionServiceImpl">
                    <constructor-arg name="injectionDao" ref="injectionDao"></constructor-arg>
                </bean>
                
                <bean id="injectionDao" class="com.jing.spring.bean.InjectionDaoImpl"></bean>
         </beans>
        private InjectionDao injectionDaoss;
        
            InjectionServiceImpl(InjectionDao injectionDao){
                this.injectionDaoss=injectionDao;
            }
            public void save(String arg) {
                System.out.print("InjectionServiceImpl中的arg==="+arg+"\n");
                //邏輯處理
                arg=arg+":"+this.hashCode();
                injectionDaoss.save(arg);
            }

Bean的配置項

  • Id
  • Class
  • Scope
  • Contructor arguments
  • Properties
  • Autowiring mode
  • lazy_initialization mode
  • Initialization/destruction mothod

Bean的作用域

  • singleton:單例。一個Bean容器中只存在一個Bean物件。
  • prototype:每次請求建立例項都會產生一個新的例項,destroy不生效。
  • request:每次請求建立一個新的例項且在當前request內有效。
  • session:同上,每次http請求建立一個新的例項,且在當前session有效。
  • global session:基於portlet的web中有效(portlet定義了 global session)。如果是在web中,同session。使用在多個系統之間,一個session控制不了多個系統。

Bean的生命週期

  • 定義:XML檔案中<bean>的定義
  • 初始化:獲取一個例項的時候
  • 使用:使用
  • 銷燬:銷燬  
  • 初始化/銷燬方法:這兩個方法是為了 在初始化/銷燬Bean容器的時候執行一些額外的方法
    • 針對Bean例項的銷燬,只有在Bean是單例singleton模式的前提下,Bean才會隨著Bean容器的銷燬而銷燬。在原型prototype的模式下,Bean例項在建立後,就會交由使用者進行管理,所以此時Bean例項的銷燬不是由Bean容器決定。舉例:在原型模式中,根據電影票類初始化兩個例項,也就是兩張電影票,這個時候,不能因為一張電影票的作廢,另一張電影票也隨之作廢。電影票的管理應該交由使用者來管理。
    • 方式一:XML中每一個Bean例項宣告一個初始化方法/銷燬方法
      <?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
              http://www.springframework.org/schema/beans/spring-beans.xsd" >
              
          <bean id="springLifeDate" class="com.jing.spring.lifedate.SpringLifeDate" init-method="start" destroy-method="end"></bean>
          
       </beans>
      package com.jing.spring.lifedate;

      public class SpringLifeDate1 {

      public void start(){
      System.out.println("SpringLifeDate開始執行。。。。");
      }
      public void excecute(){
      System.out.println("SpringLifeDate執行中。。。。");
      }
      public void end(){
      System.out.println("SpringLifeDate執行結束。。。。");
      }
      }
       

      PS:這種方法針對每個Bean設定的初始化/銷燬時執行的方法。在Bean容器初始化時主動執行init-method設定的類中的方法,Bean容器銷燬後執行destroy-method設定的方法。如果在XML中進行方法設定,Bean類中創造方法,會報錯。

    • 方式二:在Bean的類中實現介面,實現初始化方法/銷燬方法
      package com.jing.spring.lifedate;

      import org.springframework.beans.factory.DisposableBean;
      import org.springframework.beans.factory.InitializingBean;

      public class SpringLifeDate2 implements InitializingBean, DisposableBean {

      public void afterPropertiesSet() throws Exception {
      System.out.println("SpringLifeDate開始執行。。。。");
      }
      public void excecute(){
      System.out.println("SpringLifeDate執行中。。。。");
      }
      public void destroy() throws Exception {
      System.out.println("SpringLifeDate執行結束。。。。");
      }
      }

       PS:這種方法是Bean中實現介面實現Bean初始化/銷燬時執行的方法。Bean初始化後執行的方法需要實現InitializingBean介面重寫afterPropertiesSet方法,Bean銷燬後執行的方法需要實現DisposableBean介面重寫destroy方法。

    • 方式三:在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
              http://www.springframework.org/schema/beans/spring-beans.xsd"
          default-init-method="defaultInit" default-destroy-method="defaultDestroy" >
       </beans>
      package com.jing.spring.lifedate;
      
      public class SpringLifeDate3 {
          public void defaultInit() throws Exception {
              System.out.println("SpringLifeDate3開始執行。。。。");
          }
          public void excecute(){
              System.out.println("SpringLifeDate執行中。。。。");
          }
          public void defaultDestroy() throws Exception {
              System.out.println("SpringLifeDate3執行結束。。。。");
          }
      }

      PS:這種方式生命Bean的初始化/銷燬方法,在類中沒有相對應得方法,也不會報錯。

    • 執行順序
      • 在三種方式同時存在的情況下:只會執行方式一(每一個Bean例項宣告)和方式二(實現類方式)中定義的初始化/銷燬方法,執行順序為方式二(實現類方式)>方式一(每一個Bean例項宣告)
      • 在方式三(全域性配置)和其他任一方式同時存在,方式三(全域性配置)都不會執行,只會執行另一種方式中定義的初始化/銷燬方法。
  • Next