1. 程式人生 > 其它 >Spring -工廠高階特性

Spring -工廠高階特性

1、物件生命週期

什麼是物件的⽣命週期

指的是一個物件建立、存活、消亡的一個完整的過程

那為什麼要學習物件的⽣命週期?

由Spring負責物件的建立、存活、銷燬,瞭解 ⽣命週期,有利於我們使⽤好Spring為我們創 建的物件

⽣命週期的3個階段

  • 建立

    spring工廠根據物件作用域不同建立時機也不同

1. scope="singleton"
Spring⼯⼚建立的同時,物件的建立
注意:設定scope=singleton 這種情況下 也需要在獲取物件的同時,建立物件<bean lazy-init="true"/>

2. scope="prototype"
Spring⼯⼚會在獲取物件的同時,建立物件 即在ctx.getBean("")的時候
  • 初始化
Spring⼯⼚在建立完物件後,調⽤物件的初始化⽅法,完成對應的初始化操作(資源的初始化:資料庫 IO ⽹絡)
1. 初始化⽅法提供:程式設計師根據需求,提供初始化⽅法,最終完成初始化操作
2. 初始化⽅法調⽤:Spring⼯⼚進⾏調⽤
實現方式:
1. 實現InitializingBean接⼝,重寫afterProperitesSet()方法
2. 自定義初始化方法public void myInit(){},並顯示指定
    <bean id="product"class="xxx.Product" init-method="myInit"/>
3.細節分析:如果⼀個物件即實現InitializingBean 同時⼜提供的 普通的初始化⽅法 順序是
   先InitializingBean,後普通初始化⽅法
  • 銷燬
Spring銷燬物件前,會調⽤物件的銷燬⽅法,完成銷燬操作(資源的釋放操作io.close()connection.close();)
1. Spring什麼時候銷燬所建立的物件?
 ctx.close();
2. 銷燬⽅法:程式設計師根據⾃⼰的需求,定義銷燬⽅法,完成銷燬操作
 調⽤:Spring⼯⼚完成調⽤
1. 實現DisposableBean介面,重寫destroy()方法
2. 自定義銷燬方法myDestroy(),並顯示指定
   <bean id="" class="" initmethod="" destroy-method="myDestroy"/>
3. 細節分析:銷燬⽅法的操作只適⽤於 scope="singleton"

2、配置檔案引數化

把Spring配置⽂件中需要經常修改的字串資訊,轉移到⼀個更⼩的配置⽂件中
1. Spring的配置⽂件中存在需要經常修改的字串?存在 以資料庫連線相關的引數 代表
2. 經常變化字串,在Spring的配置⽂件中,直接修改不利於項⽬維護(修改)
3. 轉移到⼀個⼩的配置⽂件(.properties)利於維護(修改)
配置⽂件引數化:利於Spring配置⽂件的維護(修改)

配置⽂件引數的開發步驟

  • 提供⼀個⼩的配置⽂件(.properities)

    名字:隨便
    放置位置:隨便
    jdbc.driverClassName =com.mysql.jdbc.Driver
    jdbc.url =jdbc:mysql://localhost:3306/jwww?useSSL=false
    jdbc.username = root
    jdbc.password = 123456
    
  • Spring的配置⽂件與⼩配置⽂件進⾏整合(引入)

    applicationContext.xml
    <context:property-placeholderlocation="classpath:/db.properties"/>
    
  • 在Spring配置⽂件中通過${key}獲取⼩配置⽂件中 對應的值

3、自定義型別轉化器

型別轉換器

作⽤:Spring通過型別轉換器把配置⽂件中字串型別的資料,轉換成了物件中成員變數對應型別的資料,進⽽完成了注⼊.

⾃定義型別轉換器

原因:當Spring內部沒有提供特定型別轉換器時,⽽程式設計師在應⽤的過程中還需要使⽤,那麼就需要程式設計師⾃⼰定義型別轉換器.
  • 類 implements Converter接⼝

    public class MyDateConverter implements Converter<String,Date> {
     /*
     convert⽅法作⽤:String ---> DateSimpleDateFormat sdf = newSimpleDateFormat();
     sdf.parset(String) ---> Date
     param:source 代表的是配置⽂件中 ⽇期字串 <value>2020-10-1</value>
     return : 當把轉換好的Date作為convert⽅法的返回值後,Spring⾃動的為birthday屬性進⾏注⼊(賦值)
     */
     @Override
     public Date convert(Stringsource) {
     Date date = null;
     try {
         SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd");
         date = sdf.parse(source);
     } catch (ParseException e) {
    	e.printStackTrace();
     }
         return date;
     }
    }
    
  • 在Spring的配置⽂件中進行配置

    • MyDateConverter物件創建出來

      <bean id="myDateConverter" class="xxxx.MyDateConverter"/>
      
    • 型別轉化器註冊(告訴spring是一個型別轉換器)

      ⽬的:告知Spring框架,我們所建立的MyDateConverter是⼀個型別轉換器
      <!--⽤於註冊型別轉換器-->
      <bean id="conversionService"class="org.springframework.context.support.ConversionServiceFactoryBean">
           <property name="converters">
               <set>
                   <ref bean="myDateConverter"/>
               </set>
           </property>
      </bean>
      

細節

  • MyDateConverter中的⽇期的格式,通過依賴注⼊ 的⽅式,由配置⽂件完成賦值。

    public class MyDateConverter implements Converter<String,Date> {
     /*
     convert⽅法作⽤:String ---> DateSimpleDateFormat sdf = newSimpleDateFormat();
     sdf.parset(String) ---> Date
     param:source 代表的是配置⽂件中 ⽇期字串 <value>2020-10-1</value>
     return : 當把轉換好的Date作為convert⽅法的返回值後,Spring⾃動的為birthday屬性進⾏注⼊(賦值)
     */
     //提取日期格式字串
     private String pattern;
     //提供set、get方法供spring屬性注入   
     public String getPattern() {
         return pattern;
     }
     public voidsetPattern(String pattern) {
         this.pattern = pattern;
     }   
        
        
        
        
     @Override
     public Date convert(Stringsource) {
     Date date = null;
     try {
         SimpleDateFormat sdf = newSimpleDateFormat(pattern); //抽取
         date = sdf.parse(source);
     } catch (ParseException e) {
    	e.printStackTrace();
     }
         return date;
     }
    }
    

    拿到配置檔案配置

    <!--Spring建立MyDateConverter型別物件-->
    <bean id="myDateConverter"class="com.baizhiedu.converter.MyDateConverter">
         <property name="pattern" value="yyyy-MM-dd"/>
    </bean>
    
    • ConversionSeviceFactoryBean 定義 id屬性 值必須 conversionService

    • Spring框架內建⽇期型別的轉換器(不符合國人閱讀習慣)

      ⽇期格式:2020/05/01 (不⽀持 :2020-05-01)
      

4、後置處理Bean

BeanPostProcessor作⽤:對Spring⼯⼚所建立的物件,進⾏再加⼯。
底層實現:AOP
注意:BeanPostProcessor接⼝
         xxxx(){
      }

後置處理Bean的運⾏原理分析

程式設計師實現BeanPostProcessor規定接⼝中的⽅法:
Object postProcessBeforeInitiallization(Object bean String beanName)
作⽤:Spring建立完物件,並進⾏注⼊後,可以運⾏Before⽅法進⾏加⼯獲得Spring建立好的物件 :通過⽅法的引數最終通過返回值交給Spring框架

Object postProcessAfterInitiallization(Object bean String beanName)
作⽤:Spring執⾏完物件的初始化操作後,可以運⾏After⽅法進⾏加⼯獲得Spring建立好的物件 :通過⽅法的引數最終通過返回值交給Spring框架

實戰中:
BeanPostProcessor的開發步驟
1. 類 實現 BeanPostProcessor接⼝很少處理Spring的初始化操作:沒有必要區分Before After。只需要實現其中的⼀個After⽅法即可
注意:
postProcessBeforeInitiallization
 return bean物件
  • BeanPostProcessor的開發步驟

    1. 類 實現 BeanPostProcessor接⼝

      public class MyBeanPostProcessor implements BeanPostProcessor
      {
           @Override
           public Object postProcessBeforeInitialization(Object bean, StringbeanName) throws
          BeansException {
               return bean;
           }
          @Override
           public Object postProcessAfterInitialization(Object bean, String beanName) throws
          BeansException {
               Categroy categroy =(Categroy) bean;
               categroy.setName("xiaowb");
               return categroy;
           }
      }
      
    2. Spring的配置⽂件中進⾏配置

      <bean id="myBeanPostProcessor" class="xxx.MyBeanPostProcessor"/>
      
    3. BeanPostProcessor細節

      BeanPostProcessor會對Spring⼯⼚中所有建立的物件進⾏加⼯。