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