亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

    Spring生命周期回調與容器擴展詳解

     更新時間:2017年12月25日 14:27:43   作者:liuxigiant  
    這篇文章主要介紹了Spring生命周期回調與容器擴展詳解,具有一定借鑒價值,需要的朋友可以參考下。

    本篇主要總結下Spring容器在初始化實例前后,提供的一些回調方法和可擴展點。利用這些方法和擴展點,可以實現在Spring初始化實例前后做一些特殊邏輯處理。

    下面主要介紹:

    類級別的生命周期初始化回調方法init-method配置、InitializingBean接口和PostConstruct注解

    容器級別的擴展BeanPostProcessor接口和BeanFactoryPostProcessor接口

    1.類級別生命周期回調

    1.1init-method

    參照:Springbeanxsdinit-method

    init-method是在Spring配置文件中聲明bean的時候的一個配置項。init-method配置項的值為類中的一個無參方法,但可拋出異常。該方法會在Spring容器實例化對象并設置完屬性值之后被調用。

    init-method能實現的功能與InitializingBean接口、PostConstruct注解一致

    Spring配置文件及測試類如下:

    <bean id = "initMethodBeanService" class="name.liuxi.spring.ext.InitMethodBeanService" init-method="init">
       <property name="f2" value="2"/>
    </bean>

    測試類如下:

    public class InitMethodBeanService {
    	private static Integer f1;
    	private Integer f2;
    	static {
    		f1 = 1;
    		System.out.println("InitMethodBeanService static block execute...");
    	}
    	public InitMethodBeanService(){
    		System.out.println("InitMethodBeanService construct method execute...");
    	}
    	public void init(){
    		System.out.println("InitMethodBeanService init method execute...");
    	}
    	public Integer getF2() {
    		return f2;
    	}
    	public void setF2(Integer f2) {
    		this.f2 = f2;
    		System.out.println("InitMethodBeanService setF2 method execute...");
    	}
    }

    執(zhí)行結果打印如下:

    InitMethodBeanService static block execute...
    InitMethodBeanService construct method execute...
    InitMethodBeanService setF2 method execute...
    InitMethodBeanService init method execute...
    test method execute...

    1.2InitializingBean接口

    參照:Spring官方文檔beans-factory-lifecycle-initializingbean

    InitializingBean接口中聲明了一個方法afterPropertiesSet,該方法會在Spring容器實例化對象并設置完屬性值之后被調用。和上面的init-method實現的功能一致,因此Spring不推薦使用InitializingBean接口。

    例子比較簡單,不列出來了

    1.3PostConstruct注解

    翻譯:Spring官方文檔beans-postconstruct-and-predestroy-annotations

    @PostConstruct注解是和init-method、InitializingBean接口實現效果一致的生命周期回調方法

    @PostConstruct
    public void postConstruct(){
      System.out.println("PostConstructService postConstruct method execute...");
    }

    總結下上面三個生命周期回調方法init-method、InitializingBean接口、@PostConstruct注解

    1.都是針對單個類的實例化后處理

    2.執(zhí)行時間都是在類實例化完成,且成員變量完成注入之后調用的

    3.對于init-method,還可以在Spring配置文件的beans元素下配置默認初始化方法,配置項為default-init-method

    4.若以上三種方式配置的初始化方法都不一樣,則執(zhí)行順序為:@PostConstruct注解方法–>InitializingBean的afterPropertiesSet–>init-method方法;若三種方式配置的方法一樣,則方法只執(zhí)行一次(參照:Spring官方文檔beans-factory-lifecycle-combined-effect

    5.有初始化回調方法,對應的也有銷毀的回調方法。@PostConstruct注解方法–>InitializingBean的afterPropertiesSet–>init-method方法分別對應@PreDestroy注解方法–>DisposableBean的destroy–>destroy-method方法

    2.容器級別擴展

    翻譯:Spring官方文檔3.8ContainerExtensionPoints

    通常情況下,開發(fā)人員無需自定義實現一個ApplicationContext的子類去擴展SpringIOC容器,SpringIOC容器通過對外暴露的一些接口,可實現對SpringIOC容器的擴展。

    2.1BeanPostProcessor接口

    2.1.1bean實例初始化后處理器及后處理器鏈

    BeanPostProcessor接口定義了兩個容器級別的回調方法postProcessBeforeInitialization和postProcessAfterInitialization,用于在初始化實例后的一些邏輯處理,會針對容器中的所有實例進行處理。實現了BeanPostProcessor接口的類,稱之為bean實例初始化后處理器。

    若在SpringIOC容器中集成了多個實例初始化后處理器,這些后處理器構成的集合稱之為bean實例初始化后處理器鏈。

    postProcessBeforeInitialization方法在類實例化且成員變量注入完成之后執(zhí)行,初始化方法(例如InitializingBean的afterPropertiesSet方法)之前執(zhí)行

    postProcessAfterInitialization方法在類實例化且成員變量注入完成之后執(zhí)行,初始化方法(例如InitializingBean的afterPropertiesSet方法)之后執(zhí)行

    總結:

    1.實例初始化后處理器多用于對實例的一些代理操作。Spring中一些使用到AOP的特性也是通過后處理器的方式實現的。

    2.實例初始化后處理器鏈是多個后處理器,就會有執(zhí)行順序的問題,可以通過實現Ordered接口,指定后處理的執(zhí)行順序,Ordered接口聲明了getOrder方法,方法返回值越小,后處理的優(yōu)先級越高,越早執(zhí)行。

    3.在通過實現BeanPostProcessor接口自定義實例初始化后處理器的時候,建議也實現Ordered接口,指定優(yōu)先級。

    4.這些后處理器的作用域是當前的SpringIOC容器,即后處理器被聲明的SpringIOC容器。對于有層次結構的SpringIOC容器,實例初始化后處理器鏈不會作用于其他容器所初始化的實例上,即使兩個容器在同一層次結構上。

    5.實例初始化后處理器的實現類只需要和普通的被Spring管理的bean一樣聲明,SpringIOC容器就會自動檢測到,并添加到實例初始化后處理器鏈中。

    6.相對于自動檢測,我們也可以調用ConfigurableBeanFactory的addBeanPostProcessor方法,以編程的方式將一個實例初始化后處理器添加到實例初始化后處理器鏈中。這在需要判定添加條件的場景下比較實用。這種編程式的方式會忽略到實現的Ordered接口所指定的順序,而會作用于所有的被自動檢測的實例初始化后處理器之前。

    2.1.2bean實例初始化后處理器與AOP

    BeanPostProcessor是一個特殊的接口,實現這個接口的類會被作為Spring管理的bean的實例的后處理器。因此,在Spring應用上下文啟動的一個特殊階段,會直接初始化所有實現了BeanPostProcessor接口的實例,以及該實例所引用的類也會被實例化。然后作為后處理器應用于其他普通實例。

    由于AOP的自動代理是以實例化后處理器的方式實現的,所以無論是bean實例初始化后處理器鏈實例還是其引用的實例,都不能被自動代理。因而,不要在這些實例上進行切面織入。(對于這些實例,會產生這樣的日志消息:“類foo不能被所有的實例化后處理器鏈處理,即不能被自動代理”)。

    注意:當實例化后處理器以autowiring或@Resource的方式引用其他bean,Spring容器在以類型匹配依賴注入的時候,可能會注入非指定的bean(例如:實例化后處理器實現類以Resource方式依賴bean,若set方法和被依賴的bean的名稱一致或者被依賴bean未聲明名稱,則依賴注入會以類型匹配的方式注入,此時可能會注入非指定的bean)。這也會導致自動代理或其他方式的實例化后處理器處理失敗。

    2.1.3bean實例初始化后處理器示例

    public class BeanPostProcessorService implements BeanPostProcessor {
    	@Override
    	  public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
    		System.out.println("BeanPostProcessorService postProcessAfterInitialization method execute... ");
    		return o;
    	}
    	@Override
    	  public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
    		System.out.println("BeanPostProcessorService postProcessBeforeInitialization method execute... ");
    		return o;
    	}
    }

    2.2BeanFactoryPostProcessor接口

    2.2.1beanfactory后處理器

    通過實現BeanFactoryPostProcessor接口,可以讀取容器所管理的bean的配置元數據,在bean完成實例化之前進行更改,這些bean稱之為beanfactory后處理器。

    BeanFactoryPostProcessors與BeanPostProcessor接口的異同點:

    相同點:

    都是容器級別的后處理器

    都可配置多個后處理器,并通過實現Ordered接口,指定執(zhí)行順序

    都是針對接口聲明的容器中所管理的bean進行處理,在有層級結構的容器中,不能處理其他容器中的bean,即使兩個容器是同一層次

    都是只需要在容器中和普通bean一樣聲明,容器會自動檢測到,并注冊為后處理器

    會忽略延遲初始化屬性配置

    不同點:

    BeanFactoryPostProcessors接口在bean**實例化前處理bean的配置元數據,BeanPostProcessor接口在bean實例化后處理bean的實例**

    BeanFactoryPostProcessors接口也能通過BeanFactory.getBean()方法獲取bean的實例,這樣會引起bean的實例化。由于BeanFactoryPostProcessors后處理器是在所有bean實例化之前執(zhí)行,通過BeanFactory.getBean()方法會導致提前實例化bean,從而打破容器標準的生命周期,這樣可能會引起一些負面的影響(例如:提前實例化的bean會忽略bean實例化后處理器的處理)。

    2.2.2Spring內置及自定義beanfactory后處理器

    Spring內置了一些beanfactory后處理器(例如:PropertyPlaceholderConfigurer和PropertyOverrideConfigurer)。同時也支持實現BeanFactoryPostProcessor接口,自定義beanfactory后處理器。下面說說Spring內置的兩個后處理器和自定義后處理器。

    PropertyPlaceholderConfigurer

    Spring為了避免主要的XML定義文件的修改而引起的風險,提供了配置分離,可以將一些可能變更的變量配置到屬性配置文件中,并在XML定義文件中以占位符的方式引用。這樣,修改配置只需要修改屬性配置文件即可。PropertyPlaceholderConfigurer用于檢測占位符,并替換占位符為配置屬性值。示例如下:

    PropertyPlaceholderConfigurer通過jdbc.properties屬性配置文件,在運行時,將dataSource這個bean中數據庫相關信息的屬性占位符替換成對應的配置值。

    XML配置如下:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="locations" value="classpath:com/foo/jdbc.properties"/>
    </bean>
    
    <bean id="dataSource" destroy-method="close"
        class="org.apache.commons.dbcp.BasicDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}"/>
      <property name="url" value="${jdbc.url}"/>
      <property name="username" value="${jdbc.username}"/>
      <property name="password" value="${jdbc.password}"/>
    </bean>

    屬性配置文件jdbc.properties如下:

    jdbc.driverClassName=org.hsqldb.jdbcDriver
    jdbc.url=jdbc:hsqldb:hsql://production:9002
    jdbc.username=sa
    jdbc.password=root

    PropertyPlaceholderConfigurer不僅支持屬性配置文件的讀取,也支持讀取系統(tǒng)屬性。通過systemPropertiesMode屬性值可配置讀取優(yōu)先級。各種取值說明如下:

    0:不讀取系統(tǒng)屬性

    1:若引用的屬性配置文件中未檢索到對應占位符的配置,則讀取系統(tǒng)屬性。默認為1

    2:先讀取系統(tǒng)屬性,再讀取引用的屬性配置文件。這種配置可能導致系統(tǒng)屬性覆蓋配置文件。

    PropertyOverrideConfigurer

    PropertyOverrideConfigurer類可以通過引用屬性配置文件,直接給容器中的bean賦值。當一個bean的屬性被多個PropertyOverrideConfigurer類實例賦值時,最后一個的值會覆蓋前面的。

    還是以上面給上面的dataSource的bean賦值為例:

    PropertyOverrideConfigurer類對屬性配置文件的引用使用一個新的方式,如下:

    <context:property-override location="classpath:override.properties"/>

    override.properties屬性配置文件的屬性的命名規(guī)則和上面不同(上面例子中需要保證屬性名和占位符一致),命名規(guī)則是beanName.property

    dataSource.driverClassName=com.mysql.jdbc.Driver
    dataSource.url=jdbc:mysql:mydb
    dataSource.username=sa
    dataSource.password=root

    支持復合屬性的賦值,但是要保證引用被賦值屬性的對象非空
    例如:foo.fred.bob.sammy=123
    自定義bean factory后處理器

    自定義bean factory后處理器就是實現BeanFactoryPostProcessor接口,完成對Spring容器管理的bean的配置元數據進行修改。例如:修改類屬性注入的值,示例如下:

    定義一個用戶類UserBean

    public class UserBean {
    	private String userName;
    	public String getUserName() {
    		return userName;
    	}
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    }

    Spring XML配置文件配置用戶類,并給用戶名屬性userName注入值haha

    <bean class="name.liuxi.spring.ext.BeanFactoryPostProcessorService"/>
    <bean id="user" class="name.liuxi.spring.ext.UserBean">
       <property name="userName" value="haha"/>
    </bean>

    下面是自定義的bean factory后處理器,修改屬性userName的值為heihei

    public class BeanFactoryPostProcessorService implements BeanFactoryPostProcessor {
      @Override
      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessorService postProcessBeanFactory method execut...");
        BeanDefinition bd = beanFactory.getBeanDefinition("user");
        MutablePropertyValues pv = bd.getPropertyValues();
        if(pv.contains("userName"))
        {
          pv.addPropertyValue("userName", "heihei");
        }
      }
    }

    總結

    以上就是本文關于Spring生命周期回調與容器擴展詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

    淺談自定義注解在Spring中的應用

    Spring的IOC代碼解析

    springMVC攔截器HandlerInterceptor用法代碼示例

    如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

    相關文章

    • SpringBoot服務器端解決跨域問題

      SpringBoot服務器端解決跨域問題

      這篇文章主要介紹了SpringBoot服務器端解決跨域問題,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
      2020-11-11
    • 詳解Java的Hibernate框架中的搜索工具的運用

      詳解Java的Hibernate框架中的搜索工具的運用

      這篇文章主要介紹了詳解Java的Hibernate框架中的搜索工具的運用,Hibernate是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
      2015-11-11
    • 使用spring stream發(fā)送消息代碼實例

      使用spring stream發(fā)送消息代碼實例

      這篇文章主要介紹了使用spring stream發(fā)送消息代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
      2020-05-05
    • java如何判斷一個數是否是素數(質數)

      java如何判斷一個數是否是素數(質數)

      這篇文章主要介紹了java如何判斷一個數是否是素數(質數),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
      2021-09-09
    • mybatis報Query?was?Empty異常的問題

      mybatis報Query?was?Empty異常的問題

      這篇文章主要介紹了mybatis報Query?was?Empty異常的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
      2022-03-03
    • Java實現Dijkstra算法的示例代碼

      Java實現Dijkstra算法的示例代碼

      Dijkstra(迪杰斯特拉)算法是典型的單源最短路徑算法,用于計算一個節(jié)點到其他所有節(jié)點的最短路徑。本文主要介紹了實現這一算法的Java代碼,需要的可以參考一下
      2022-07-07
    • win10下定時運行與開機自啟動jar包的方法記錄

      win10下定時運行與開機自啟動jar包的方法記錄

      這篇文章主要給大家介紹了關于win10下定時運行與開機自啟動jar包的相關資料,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
      2020-11-11
    • Java異常(Exception)處理以及常見異常總結

      Java異常(Exception)處理以及常見異??偨Y

      在《Java編程思想》中這樣定義異常,阻止當前方法或作用域繼續(xù)執(zhí)行的問題,雖然java中有異常處理機制,但是要明確一點,決不應該用"正常"的態(tài)度來看待異常,這篇文章主要給大家介紹了關于Java異常(Exception)處理以及常見異常的相關資料,需要的朋友可以參考下
      2021-10-10
    • 安裝elasticsearch-analysis-ik中文分詞器的步驟講解

      安裝elasticsearch-analysis-ik中文分詞器的步驟講解

      今天小編就為大家分享一篇關于安裝elasticsearch-analysis-ik中文分詞器的步驟講解,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
      2019-02-02
    • Mybatis執(zhí)行插入語句后并返回主鍵ID問題

      Mybatis執(zhí)行插入語句后并返回主鍵ID問題

      這篇文章主要介紹了Mybatis執(zhí)行插入語句后并返回主鍵ID問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
      2023-03-03

    最新評論