摘要:如果該方法的返回值代替原本該生成的目標(biāo)對象,后續(xù)只有方法會調(diào)用,其它方法不再調(diào)用否則按照正常的流程走方法在目標(biāo)對象實例化之后調(diào)用,這個時候?qū)ο笠呀?jīng)被實例化,但是該實例的屬性還未被設(shè)置,都是。
我們可能會在 Bean 對象創(chuàng)建完成后, 執(zhí)行某些操作或在銷毀前做某些操作.
我們可以實現(xiàn) InitializingBean 或 DisposableBean 接口
public class Test implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { } @Override public void destroy() throws Exception { } }
當(dāng)然我們可以使用注解來實現(xiàn)
@PostConstruct public void afterPropertiesSet() throws Exception { System.out.println("-- init --"); } @PreDestroy public void destroy() throws Exception { System.out.println("-- destroy --"); }
還有另一種方法可以使用 @Bean 注解
public void afterPropertiesSet() throws Exception { System.out.println("-- init --"); } public void destroy() throws Exception { System.out.println("-- destroy --"); } @Bean(initMethod = "afterPropertiesSet", destroyMethod = "destroy") public Test getTest() { return new Test(); }
要注意的是, 初始化和銷毀的方法只是針對當(dāng)前的 bean 不會對其它 bean 產(chǎn)生影響.
如果想所有的 bean 在創(chuàng)建前或創(chuàng)建后添加一些處理邏輯, 可以使用 BeanPostProcessor 接口. 也可以配合 Ordered 接口來設(shè)置執(zhí)行順序.
如果有兩個容器, 他們之間不會相互影響.
BeanPostProcessor 接口由兩個回調(diào)方法組成.
public interface BeanPostProcessor { // 初始化之前的操作 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; // 初始化之后的操作 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
四個子接口:
1.DestructionAwareBeanPostProcessor
// 該方法是bean在Spring在容器中被銷毀之前調(diào)用 void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
2.InstantiationAwareBeanPostProcessor
// postProcessBeforeInstantiation方法的作用在目標(biāo)對象被實例化之前調(diào)用的方法,可以返回目標(biāo)實例的一個代理用來代替目標(biāo)實例 // beanClass參數(shù)表示目標(biāo)對象的類型,beanName是目標(biāo)實例在Spring容器中的name // 返回值類型是Object,如果返回的是非null對象,接下來除了postProcessAfterInitialization方法會被執(zhí)行以外,其它bean構(gòu)造的那些方法都不再執(zhí)行。否則那些過程以及postProcessAfterInitialization方法都會執(zhí)行 Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException; // postProcessAfterInstantiation方法的作用在目標(biāo)對象被實例化之后并且在屬性值被populate之前調(diào)用 // bean參數(shù)是目標(biāo)實例(這個時候目標(biāo)對象已經(jīng)被實例化但是該實例的屬性還沒有被設(shè)置),beanName是目標(biāo)實例在Spring容器中的name // 返回值是boolean類型,如果返回true,目標(biāo)實例內(nèi)部的返回值會被populate,否則populate這個過程會被忽視 boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; // postProcessPropertyValues方法的作用在屬性中被設(shè)置到目標(biāo)實例之前調(diào)用,可以修改屬性的設(shè)置 // pvs參數(shù)表示參數(shù)屬性值(從BeanDefinition中獲取),pds代表參數(shù)的描述信息(比如參數(shù)名,類型等描述信息),bean參數(shù)是目標(biāo)實例,beanName是目標(biāo)實例在Spring容器中的name // 返回值是PropertyValues,可以使用一個全新的PropertyValues代替原先的PropertyValues用來覆蓋屬性設(shè)置或者直接在參數(shù)pvs上修改。如果返回值是null,那么會忽略屬性設(shè)置這個過程(所有屬性不論使用什么注解,最后都是null) PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
注: 此接口為專用接口, 主要用于框架內(nèi)部使用. 建議盡可能地實現(xiàn)普通 BeanPostProcessor 接口, 或 InstantiationAwareBeanPostProcessorAdapter 派生, 以避免擴(kuò)展到該接口.
InstantiationAwareBeanPostProcessor接口繼承BeanPostProcessor接口,它內(nèi)部提供了3個方法,再加上BeanPostProcessor接口內(nèi)部的2個方法,所以實現(xiàn)這個接口需要實現(xiàn)5個方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目標(biāo)對象的實例化過程中需要處理的事情,包括實例化對象的前后過程以及實例的屬性設(shè)置
postProcessBeforeInstantiation方法是最先執(zhí)行的方法,它在目標(biāo)對象實例化之前調(diào)用,該方法的返回值類型是Object,我們可以返回任何類型的值。由于這個時候目標(biāo)對象還未實例化,所以這個返回值可以用來代替原本該生成的目標(biāo)對象的實例(比如代理對象)。如果該方法的返回值代替原本該生成的目標(biāo)對象,后續(xù)只有postProcessAfterInitialization方法會調(diào)用,其它方法不再調(diào)用;否則按照正常的流程走
postProcessAfterInstantiation方法在目標(biāo)對象實例化之后調(diào)用,這個時候?qū)ο笠呀?jīng)被實例化,但是該實例的屬性還未被設(shè)置,都是null。如果該方法返回false,會忽略屬性值的設(shè)置;如果返回true,會按照正常流程設(shè)置屬性值
postProcessPropertyValues方法對屬性值進(jìn)行修改(這個時候?qū)傩灾颠€未被設(shè)置,但是我們可以修改原本該設(shè)置進(jìn)去的屬性值)。如果postProcessAfterInstantiation方法返回false,該方法不會被調(diào)用。可以在該方法內(nèi)對屬性值進(jìn)行修改
父接口BeanPostProcessor的2個方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目標(biāo)對象被實例化之后,并且屬性也被設(shè)置之后調(diào)用的
Instantiation表示實例化,Initialization表示初始化。實例化的意思在對象還未生成,初始化的意思在對象已經(jīng)生成
3.SmartInstantiationAwareBeanPostProcessor
// 預(yù)測Bean的類型,返回第一個預(yù)測成功的Class類型,如果不能預(yù)測返回null Class> predictBeanType(Class> beanClass, String beanName) throws BeansException; // 選擇合適的構(gòu)造器,比如目標(biāo)對象有多個構(gòu)造器,在這里可以進(jìn)行一些定制化,選擇合適的構(gòu)造器 // beanClass參數(shù)表示目標(biāo)實例的類型,beanName是目標(biāo)實例在Spring容器中的name // 返回值是個構(gòu)造器數(shù)組,如果返回null,會執(zhí)行下一個PostProcessor的determineCandidateConstructors方法;否則選取該PostProcessor選擇的構(gòu)造器 Constructor>[] determineCandidateConstructors(Class> beanClass, String beanName) throws BeansException; // 獲得提前暴露的bean引用。主要用于解決循環(huán)引用的問題 // 只有單例對象才會調(diào)用此方法 Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
SmartInstantiationAwareBeanPostProcessor接口繼承InstantiationAwareBeanPostProcessor接口,它內(nèi)部提供了3個方法,再加上父接口的5個方法,所以實現(xiàn)這個接口需要實現(xiàn)8個方法。SmartInstantiationAwareBeanPostProcessor接口的主要作用也是在于目標(biāo)對象的實例化過程中需要處理的事情。它是InstantiationAwareBeanPostProcessor接口的一個擴(kuò)展。主要在Spring框架內(nèi)部使用
predictBeanType方法用于預(yù)測Bean的類型,返回第一個預(yù)測成功的Class類型,如果不能預(yù)測返回null。主要在于BeanDefinition無法確定Bean類型的時候調(diào)用該方法來確定類型
determineCandidateConstructors方法用于選擇合適的構(gòu)造器,比如類有多個構(gòu)造器,可以實現(xiàn)這個方法選擇合適的構(gòu)造器并用于實例化對象。該方法在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之間調(diào)用,如果postProcessBeforeInstantiation方法返回了一個新的實例代替了原本該生成的實例,那么該方法會被忽略
getEarlyBeanReference主要用于解決循環(huán)引用問題。比如ReferenceA實例內(nèi)部有ReferenceB的引用,ReferenceB實例內(nèi)部有ReferenceA的引用。首先先實例化ReferenceA,實例化完成之后提前把這個bean暴露在ObjectFactory中,然后populate屬性,這個時候發(fā)現(xiàn)需要ReferenceB。然后去實例化ReferenceB,在實例化ReferenceB的時候它需要ReferenceA的實例才能繼續(xù),這個時候就會去ObjectFactory中找出了ReferenceA實例,ReferenceB順利實例化。ReferenceB實例化之后,ReferenceA的populate屬性過程也成功完成,注入了ReferenceB實例。提前把這個bean暴露在ObjectFactory中,這個ObjectFactory獲取的實例就是通過getEarlyBeanReference方法得到的
4.MergedBeanDefinitionPostProcessor
// 該方法是bean在合并Bean定義之后調(diào)用 void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72465.html
摘要:上一篇文章生命周期之我從哪里來說明了我是誰和我從哪里來的兩大哲學(xué)問題,今天我們要討論一下終極哲學(xué)我要到哪里去初始化有三種方式銷毀同樣有三種方式正所謂,天對地,雨對風(fēng)對對對雷隱隱,霧蒙蒙山花對海樹,赤日對蒼穹平仄平仄平平仄,仄平仄平仄 上一篇文章 Spring Bean 生命周期之我從哪里來 說明了我是誰? 和 我從哪里來? 的兩大哲學(xué)問題,今天我們要討論一下終極哲學(xué)我要到哪里去?sho...
摘要:初始化我們知道容器初始化后會對容器中非懶加載的,單例的以及非抽象的定義進(jìn)行的初始化操作,所以我們分析源碼的入口也就是在容器初始化的入口,分析容器初始化后在什么地方開始第一次的初始化。 前言 Spring IOC容器在初始化之后會對容器中非懶加載的,單例的以及非抽象的bean定義進(jìn)行bean的初始化操作,同時會也涉及到Bean的后置處理器以及DI(依賴注入)等行為。對于Bean的初始化,...
摘要:的在單例被破壞時由進(jìn)行方法調(diào)用。定義并實現(xiàn)這兩個接口容器創(chuàng)建完成注解是的縮寫,意思是規(guī)范提案。在創(chuàng)建完成并且屬性賦值完成來執(zhí)行初始化方法在容器銷毀之前回調(diào)通知支持自動裝配,類似。 Spring注解應(yīng)用篇--IOC容器Bean生命周期 這是Spring注解專題系類文章,本系類文章適合Spring入門者或者原理入門者,小編會在本系類文章下進(jìn)行企業(yè)級應(yīng)用實戰(zhàn)講解以及spring源碼跟進(jìn)。本文...
摘要:生成的兩種方式通過反射調(diào)用構(gòu)造函數(shù)通過優(yōu)點依賴關(guān)系的管理被反轉(zhuǎn)并交給容器,使復(fù)雜的依賴關(guān)系管理從應(yīng)用中解放出來。 IOC概述 1、理解: (1)控制反轉(zhuǎn)。將生成對象的控制權(quán)交IOC容器,由容器生成依賴的對象。調(diào)用類只依賴接口,而不依賴具體的實現(xiàn)類,減少了耦合。在運行的時候,才由容器將具體的實例注入到調(diào)用類的對象中。(2)依賴注入,就是向Ioc容器索要bean的過程。getBean是依賴...
摘要:如果依賴靠構(gòu)造器方式注入,則無法處理,直接會報循環(huán)依賴異常。光繼承這個接口還不夠,繼承這個接口只能獲取,要想讓生效,還需要拿到切面對象包含和才行。有了目標(biāo)對象,所有的切面類,此時就可以為生成代理對象了。 Spring 是一個輕量級的 J2EE 開源框架,其目標(biāo)是降低企業(yè)級應(yīng)用開發(fā)難度,提高企業(yè)級應(yīng)用開發(fā)效率。在日程開發(fā)中,我們會經(jīng)常使用 Spring 框架去構(gòu)建應(yīng)用。所以作為一個經(jīng)常使...
閱讀 710·2021-11-18 10:02
閱讀 2248·2021-11-15 18:13
閱讀 3174·2021-11-15 11:38
閱讀 2962·2021-09-22 15:55
閱讀 3684·2021-08-09 13:43
閱讀 2453·2021-07-25 14:19
閱讀 2461·2019-08-30 14:15
閱讀 3457·2019-08-30 14:15