真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Spring生命周期回調(diào)與容器擴(kuò)展的示例分析-創(chuàng)新互聯(lián)

小編給大家分享一下Spring生命周期回調(diào)與容器擴(kuò)展的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、霞山網(wǎng)絡(luò)推廣、微信小程序定制開(kāi)發(fā)、霞山網(wǎng)絡(luò)營(yíng)銷、霞山企業(yè)策劃、霞山品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供霞山建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

下面主要介紹:

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

容器級(jí)別的擴(kuò)展BeanPostProcessor接口和BeanFactoryPostProcessor接口

1.類級(jí)別生命周期回調(diào)

1.1init-method

參照:Springbeanxsdinit-method

init-method是在Spring配置文件中聲明bean的時(shí)候的一個(gè)配置項(xiàng)。init-method配置項(xiàng)的值為類中的一個(gè)無(wú)參方法,但可拋出異常。該方法會(huì)在Spring容器實(shí)例化對(duì)象并設(shè)置完屬性值之后被調(diào)用。

init-method能實(shí)現(xiàn)的功能與InitializingBean接口、PostConstruct注解一致

Spring配置文件及測(cè)試類如下:


   

測(cè)試類如下:

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í)行結(jié)果打印如下:

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接口中聲明了一個(gè)方法afterPropertiesSet,該方法會(huì)在Spring容器實(shí)例化對(duì)象并設(shè)置完屬性值之后被調(diào)用。和上面的init-method實(shí)現(xiàn)的功能一致,因此Spring不推薦使用InitializingBean接口。

例子比較簡(jiǎn)單,不列出來(lái)了

1.3PostConstruct注解

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

@PostConstruct注解是和init-method、InitializingBean接口實(shí)現(xiàn)效果一致的生命周期回調(diào)方法

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

總結(jié)下上面三個(gè)生命周期回調(diào)方法init-method、InitializingBean接口、@PostConstruct注解

1.都是針對(duì)單個(gè)類的實(shí)例化后處理

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

3.對(duì)于init-method,還可以在Spring配置文件的beans元素下配置默認(rèn)初始化方法,配置項(xiàng)為default-init-method

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

5.有初始化回調(diào)方法,對(duì)應(yīng)的也有銷毀的回調(diào)方法。@PostConstruct注解方法–>InitializingBean的afterPropertiesSet–>init-method方法分別對(duì)應(yīng)@PreDestroy注解方法–>DisposableBean的destroy–>destroy-method方法

2.容器級(jí)別擴(kuò)展

翻譯:Spring官方文檔3.8ContainerExtensionPoints

通常情況下,開(kāi)發(fā)人員無(wú)需自定義實(shí)現(xiàn)一個(gè)ApplicationContext的子類去擴(kuò)展SpringIOC容器,SpringIOC容器通過(guò)對(duì)外暴露的一些接口,可實(shí)現(xiàn)對(duì)SpringIOC容器的擴(kuò)展。

2.1BeanPostProcessor接口

2.1.1bean實(shí)例初始化后處理器及后處理器鏈

BeanPostProcessor接口定義了兩個(gè)容器級(jí)別的回調(diào)方法postProcessBeforeInitialization和postProcessAfterInitialization,用于在初始化實(shí)例后的一些邏輯處理,會(huì)針對(duì)容器中的所有實(shí)例進(jìn)行處理。實(shí)現(xiàn)了BeanPostProcessor接口的類,稱之為bean實(shí)例初始化后處理器。

若在SpringIOC容器中集成了多個(gè)實(shí)例初始化后處理器,這些后處理器構(gòu)成的集合稱之為bean實(shí)例初始化后處理器鏈。

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

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

總結(jié):

1.實(shí)例初始化后處理器多用于對(duì)實(shí)例的一些代理操作。Spring中一些使用到AOP的特性也是通過(guò)后處理器的方式實(shí)現(xiàn)的。

2.實(shí)例初始化后處理器鏈?zhǔn)嵌鄠€(gè)后處理器,就會(huì)有執(zhí)行順序的問(wèn)題,可以通過(guò)實(shí)現(xiàn)Ordered接口,指定后處理的執(zhí)行順序,Ordered接口聲明了getOrder方法,方法返回值越小,后處理的優(yōu)先級(jí)越高,越早執(zhí)行。

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

4.這些后處理器的作用域是當(dāng)前的SpringIOC容器,即后處理器被聲明的SpringIOC容器。對(duì)于有層次結(jié)構(gòu)的SpringIOC容器,實(shí)例初始化后處理器鏈不會(huì)作用于其他容器所初始化的實(shí)例上,即使兩個(gè)容器在同一層次結(jié)構(gòu)上。

5.實(shí)例初始化后處理器的實(shí)現(xiàn)類只需要和普通的被Spring管理的bean一樣聲明,SpringIOC容器就會(huì)自動(dòng)檢測(cè)到,并添加到實(shí)例初始化后處理器鏈中。

6.相對(duì)于自動(dòng)檢測(cè),我們也可以調(diào)用ConfigurableBeanFactory的addBeanPostProcessor方法,以編程的方式將一個(gè)實(shí)例初始化后處理器添加到實(shí)例初始化后處理器鏈中。這在需要判定添加條件的場(chǎng)景下比較實(shí)用。這種編程式的方式會(huì)忽略到實(shí)現(xiàn)的Ordered接口所指定的順序,而會(huì)作用于所有的被自動(dòng)檢測(cè)的實(shí)例初始化后處理器之前。

2.1.2bean實(shí)例初始化后處理器與AOP

BeanPostProcessor是一個(gè)特殊的接口,實(shí)現(xiàn)這個(gè)接口的類會(huì)被作為Spring管理的bean的實(shí)例的后處理器。因此,在Spring應(yīng)用上下文啟動(dòng)的一個(gè)特殊階段,會(huì)直接初始化所有實(shí)現(xiàn)了BeanPostProcessor接口的實(shí)例,以及該實(shí)例所引用的類也會(huì)被實(shí)例化。然后作為后處理器應(yīng)用于其他普通實(shí)例。

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

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

2.1.3bean實(shí)例初始化后處理器示例

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后處理器

通過(guò)實(shí)現(xiàn)BeanFactoryPostProcessor接口,可以讀取容器所管理的bean的配置元數(shù)據(jù),在bean完成實(shí)例化之前進(jìn)行更改,這些bean稱之為beanfactory后處理器。

BeanFactoryPostProcessors與BeanPostProcessor接口的異同點(diǎn):

相同點(diǎn):

都是容器級(jí)別的后處理器

都可配置多個(gè)后處理器,并通過(guò)實(shí)現(xiàn)Ordered接口,指定執(zhí)行順序

都是針對(duì)接口聲明的容器中所管理的bean進(jìn)行處理,在有層級(jí)結(jié)構(gòu)的容器中,不能處理其他容器中的bean,即使兩個(gè)容器是同一層次

都是只需要在容器中和普通bean一樣聲明,容器會(huì)自動(dòng)檢測(cè)到,并注冊(cè)為后處理器

會(huì)忽略延遲初始化屬性配置

不同點(diǎn):

BeanFactoryPostProcessors接口在bean**實(shí)例化前處理bean的配置元數(shù)據(jù),BeanPostProcessor接口在bean實(shí)例化后處理bean的實(shí)例**

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

2.2.2Spring內(nèi)置及自定義beanfactory后處理器

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

PropertyPlaceholderConfigurer

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

PropertyPlaceholderConfigurer通過(guò)jdbc.properties屬性配置文件,在運(yùn)行時(shí),將dataSource這個(gè)bean中數(shù)據(jù)庫(kù)相關(guān)信息的屬性占位符替換成對(duì)應(yīng)的配置值。

XML配置如下:


  



  
  
  
  

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

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

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

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

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

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

PropertyOverrideConfigurer

PropertyOverrideConfigurer類可以通過(guò)引用屬性配置文件,直接給容器中的bean賦值。當(dāng)一個(gè)bean的屬性被多個(gè)PropertyOverrideConfigurer類實(shí)例賦值時(shí),最后一個(gè)的值會(huì)覆蓋前面的。

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

PropertyOverrideConfigurer類對(duì)屬性配置文件的引用使用一個(gè)新的方式,如下:

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

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

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

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

定義一個(gè)用戶類UserBean

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

Spring XML配置文件配置用戶類,并給用戶名屬性u(píng)serName注入值haha



   

下面是自定義的bean factory后處理器,修改屬性u(píng)serName的值為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生命周期回調(diào)與容器擴(kuò)展的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


本文名稱:Spring生命周期回調(diào)與容器擴(kuò)展的示例分析-創(chuàng)新互聯(lián)
網(wǎng)站網(wǎng)址:http://weahome.cn/article/deihcj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部