BeanPostProcessor: Bean初始化前后回調。
InstantiationAwareBeanPostProcessor:Bean實例化前后回調。
SmartInstantiationAwareBeanPostProcessor:Bean類型,構造器,以及對Bean的引用回調。
MergedBeanDefinitionPostProcessor:合並Bean Definition后的回調。
DestructionAwareBeanPostProcessor:Bean銷毀前的回調。
InitializingBean:自定義初始化方法。
BeanPostProcessor
1.介紹
允許自定義修改新的bean實例的工廠鈎子函數,例如:檢查標記接口或使用代理包裝bean。
BPP(Bean Post Processor) Bean是一種特殊的Bean,它是在其他任何Bean之前創建並與新創建的bean交互。
通常,在postProcessBeforeInitialization方法中處理標記器接口,而在postProcessAfterInitialization方法中處理bean。
ApplicationContext可以在其bean定義中自動檢測BeanPostProcessor bean,並將這些后處理器應用於隨后創建的任何bean。
一個普通的BeanFactory允許以編程方式注冊后處理器,並將其應用於通過Bean工廠創建的所有Bean。
主要是處理Bean初始化之前以及初始化之后的回調。
先執行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。
public interface BeanPostProcessor { /** * 在任何bean初始化回調之前(例如InitializingBean的afterPropertiesSet或自定義init-method)之前, * 將此BeanPostProcessor應用於給定的新bean實例。 * 返回的Bean實例可能是原始實例的包裝。 * 默認實現按原樣返回給定的 bean。 */ @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * 在任何bean初始化回調之后(例如InitializingBean的afterPropertiesSet或自定義init-method)之后, * 將此BeanPostProcessor應用於給定的新bean實例。 * 如果是FactoryBean,則將為FactoryBean實例和由FactoryBean創建的對象(從Spring 2.0開始)調用此回調。 * 可以通過FactoryBean檢查相應bean實例來決定是應用到FactoryBean還是FactoryBean創建的對象,還是兩者都應用。 * 返回的Bean實例可能是原始實例的包裝。 * 默認實現按原樣返回給定的 bean。 */ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
2.使用
//注冊方式一 @Component public class CustomBeanPostProcessor implements BeanPostProcessor { // 傳入beanFactory private final BeanFactory beanFactory; //注冊方式二 public CustomBeanPostProcessor(BeanFactory beanFactory) { System.out.println("CustomBeanPostProcessor 實例化......"); this.beanFactory = beanFactory; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("spring中bean實例:" + beanName + " 初始化之前處理......"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("spring中bean實例:" + beanName + " 初始化之后處理......"); if ("person".equals(beanName)){ Field[] declaredFields = bean.getClass().getDeclaredFields(); for (Field declaredField : declaredFields) { if ("name".equals(declaredField.getName())){ try { //修改對象的屬性 declaredField.setAccessible(true); declaredField.set(bean,"哈哈哈"); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } return bean; } } // 注冊方式二 // 提示信息: is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) // 對於返回Spring BeanFactoryPostProcessor(BFPP)類型或者BeanPostProcessor(BPP)類型的@Bean方法,必須特別注意。 // 因為BFPP對象必須在容器生命周期的早期實例化,所以它們會干擾@Configuration類中的@Autowired,@ Value和@PostConstruct之類的注釋的處理。 // 為了避免這些生命周期問題,請將BFPP或BPP返回的@Bean方法標記為static @Bean public static CustomBeanPostProcessor customBeanPostProcessor(){ return new CustomBeanPostProcessor(null); } //注冊方式三 beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
3.注意
- BeanPostProcessor依賴的bean,不會執行BeanPostProcessor的方法,因為所依賴的Bean需要在BeanPostProcessor之前創建完成。
- BeanPostProcessor以及依賴的bean無法使用AOP。
- 當使用ConfigurableBeanFactory接口的addBeanPostProcessor方法手動添加BeanPostProcessor時,只能作用於那些延遲加載的Bean或非單例bean。
- 當使用addBeanPostProcessor方式添加的BeanPostProcessor,Ordered接口的作用將失效,而是以注冊的順序執行。
- 在使用@Bean聲明工廠方法返回BeanPostProcessor實現類對象時,返回值必須是BeanPostProcessor類型,或者更低級的類型。
4.注冊點
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); // 實例化並調用所有注冊的BeanFactoryPostProcessor bean,必須在單例實例化之前調用 invokeBeanFactoryPostProcessors(beanFactory); // 注冊攔截bean創建的BeanPostProcessor處理器. registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } ... } }
5.觸發點

InstantiationAwareBeanPostProcessor
1.介紹
BeanPostProcessor的子接口,在繼承BeanPostProcessor的基礎上添加了實例化之前,以及實例化之后的回調,但設置了顯式屬性或發生自動裝配之前的回調。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /* * 實例化bean之前回調,如果該方法返回null,后面的方法都正常執行; * 如果返回一個非null對象,則bean創建過程將被短路,將直接執行postProcessAfterInitialization方法,(實例化之后和初始化之前都不執行) */ @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * 在實例化bean之后但在發生Spring屬性填充(通過顯式屬性或自動裝配)之前回調。 */ default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } /** * 在將屬性值應用於bean之前回調 */ @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } // API不推薦使用 @Deprecated @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
2.觸發點

SmartInstantiationAwareBeanPostProcessor
1.介紹
InstantiationAwareBeanPostProcessor的子接口,在繼承InstantiationAwareBeanPostProcessor的基礎上添加了返回獲取目標對象的類型,構造器,以及對Bean的引用回調。
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { // 確定給定bean的類型。 @Nullable default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException { return null; } // 確定要用於給定bean的候選構造函數。 @Nullable default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null; } // 獲取要提前暴露的bean的引用,用來支持單例對象的循環引用(一般是bean自身,如果是代理對象則需要取用代理引用) default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; } }
2.觸發點
InstantiationAwareBeanPostProcessorAdapter
1.介紹
實現了SmartInstantiationAwareBeanPostProcessor接口,而SmartInstantiationAwareBeanPostProcessor接口繼承InstantiationAwareBeanPostProcessor接口,InstantiationAwareBeanPostProcessor接口又繼承BeanPostProcessor接口;
所以InstantiationAwareBeanPostProcessorAdapter是這些接口的合集。
public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor { // 確定給定bean的類型。 @Override @Nullable public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException { return null; } // 確定給定bean的候選構造函數。 @Override @Nullable public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null; } // 獲取要提前暴露的bean的引用,用來支持單例對象的循環引用(一般是bean自身,如果是代理對象則需要取用代理引用) @Override public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; } // bean實例化之前回調 @Override @Nullable public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } // bean實例化之后回調 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } // 在將屬性值應用於bean之前回調 @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } // API不推薦使用,廢棄 @Deprecated @Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } // bean初始化之前回調 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } // bean初始化之后回調 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
MergedBeanDefinitionPostProcessor
1.介紹
BeanPostProcessor的子接口,在繼承BeanPostProcessor的基礎上添加了對合並Bean Definition后的回調。
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { // 對指定bean的給定合並bean定義進行后處理 void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName); // 重新設置指定名稱的Bean定義 default void resetBeanDefinition(String beanName) { } }
2.說明
例如:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor
,RequiredAnnotationBeanPostProcessor都是MergedBeanDefinitionPostProcessor的實現
3.觸發點

DestructionAwareBeanPostProcessor
1.介紹
BeanPostProcessor的子接口,在繼承BeanPostProcessor的基礎上添加了對Bean銷毀前的回調。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor { // 在銷毀Bean之前進行處理,僅適用於容器完全管理其生命周期的bean,單例和作用域bean。 void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException; // 判斷是否需要處理這個對象的銷毀 default boolean requiresDestruction(Object bean) { return true; } }
2.觸發點

InitializingBean
1.介紹
由bean實現的接口,可以插手Bean的初始化過程來實現自定義初始化。
public interface InitializingBean { // 自定義初始化 void afterPropertiesSet() throws Exception; }
2.觸發點

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { ... if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) {throw pae.getException();} } else { ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
3.注意點
1.Spring提供了兩種自定義初始化Bean的方法,一是實現InitializingBean接口,實現afterPropertiesSet方法,二是在配置文件中同過init-method指定,兩種方式可以同時使用。
2.如果兩個都實現,那只會執行afterPropertiesSet方法。
3.實現InitializingBean接口是直接調用afterPropertiesSet方法,比通過反射調用init-method指定的方法效率相對來說要高點。但是init-method方式消除了對spring的依賴
BeanPostProcessor接口調用順序:
-
SmartInstantiationAwareBeanPostProcessor-predictBeanType:確定給定bean的類型。
-
SmartInstantiationAwareBeanPostProcessor-getEarlyBeanReference:提前暴露的bean的引用,用來支持單例對象的循環引用。
-
InstantiationAwareBeanPostProcessor-postProcessBeforeInstantiation:bean實例化之前回調,如果有返回實例則直接跳轉到postProcessAfterInitialization方法。
-
SmartInstantiationAwareBeanPostProcessor-determineCandidateConstructors:確定給定bean的候選構造函數。
-
MergedBeanDefinitionPostProcessor-postProcessMergedBeanDefinition:對指定bean的給定合並bean定義進行后處理。
-
InstantiationAwareBeanPostProcessor-postProcessAfterInstantiation:bean實例化之后回調。
-
InstantiationAwareBeanPostProcessor-postProcessProperties:將屬性值應用於bean之前回調。
-
BeanPostProcessor-postProcessBeforeInitialization:bean初始化之前回調。
-
InitializingBean-afterPropertiesSet:自定義初始化方法。
-
xml中配置的init-method:xml指定的自定義初始化方法。
-
BeanPostProcessor-postProcessAfterInitialization:bean初始化之后回調。
-
DestructionAwareBeanPostProcessor-requiresDestruction:確定給定bean實例是否需要此后處理器銷毀。
-
DestructionAwareBeanPostProcessor-postProcessBeforeDestruction:銷毀對象前回調。

