什么是Spring的后置處理器?
Spring的后置處理器貫穿了整個springBean的實例化前后。
Spring后置處理器都有哪些類,哪些方法?
一.InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor接口繼承BeanPostProcessor接口,它內部提供了3個方法,再加上BeanPostProcessor接口內部的2個方法,所以實現這個接口需要實現5個方法。InstantiationAwareBeanPostProcessor接口的主要作用在於目標對象的實例化過程中需要處理的事情,包括實例化對象的前后過程以及實例的屬性設置在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()方法的Object bean = resolveBeforeInstantiation(beanName, mbdToUse);方法里面執行了這個后置處理器。
1、postProcessBeforeInstantiation
在目標對象實例化之前調用,方法的返回值類型是Object,我們可以返回任何類型的值。由於這個時候目標對象還未實例化,所以這個返回值可以用來代替原本該生成的目標對象的實例(一般都是代理對象)。如果該方法的返回值代替原本該生成的目標對象,后續只有postProcessAfterInitialization方法會調用,其它方法不再調用;否則按照正常的流程走。
2、postProcessAfterInstantiation
方法在目標對象實例化之后調用,這個時候對象已經被實例化,但是該實例的屬性還未被設置,都是null。如果該方法返回false,會忽略屬性值的設置;如果返回true,會按照正常流程設置。
3、postProcessPropertyValues
方法對屬性值進行修改(這個時候屬性值還未被設置,但是我們可以修改原本該設置進去的屬性值)。如果postProcessAfterInstantiation方法返回false,該方法不會被調用。可以在該方法內對屬性值進行修改。
4、postProcessBeforeInitialization&postProcessAfterInitialization
父接口BeanPostProcessor的2個方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目標對象被實例化之后,並且屬性也被設置之后調用的。
二、SmartInstantiationAwareBeanPostProcessor
智能實例化Bean后置處理器(繼承InstantiationAwareBeanPostProcessor)
1、determineCandidateConstructors
檢測Bean的構造器,可以檢測出多個候選構造器。
2、getEarlyBeanReference
循環引用的后置處理器,這個東西比較復雜, 獲得提前暴露的bean引用。主要用於解決循環引用的問題,只有單例對象才會調用此方法。
3、predictBeanType
預測bean的類型。
三、MergedBeanDefinitionPostProcessor
1、postProcessMergedBeanDefinition
緩存bean的注入信息的后置處理器,僅僅是緩存或者干脆叫做查找更加合適,沒有完成注入,注入是另外一個后置處理器的作用。
Spring后置處理器源碼展現:
第一次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.createBean()--resolveBeforeInstantiation() ---這里是springbean的生命周期開始的地方
-applyBeanPostProcessorsBeforeInstantiation()
--applyBeanPostProcessorsAfterInitialization()
1 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { 2 Object bean = null; 3 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { 4 // Make sure bean class is actually resolved at this point. 5 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 6 Class<?> targetType = determineTargetType(beanName, mbd); 7 if (targetType != null) { 8 // 第一個后置處理器執行 9 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 10 if (bean != null) { 11 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 12 } 13 } 14 } 15 mbd.beforeInstantiationResolved = (bean != null); 16 } 17 return bean; 18 }
applyBeanPostProcessorsBeforeInstantiation():
1 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { 2 //getBeanPostProcessors:拿到容器中所有實現了BeanPostProcessors接口的類 3 for (BeanPostProcessor bp : getBeanPostProcessors()) { 4 if (bp instanceof InstantiationAwareBeanPostProcessor) { 5 //第一個后置處理器 6 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 7 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); 8 if (result != null) { 9 return result; 10 } 11 } 12 } 13 return null; 14 }
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation();
第二次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.createBeanInstance()--Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);---第二次執行后置處理器使用的地方
SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors()
1 protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) 2 throws BeansException { 3 4 if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { 5 for (BeanPostProcessor bp : getBeanPostProcessors()) { 6 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { 7 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 8 Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName); 9 if (ctors != null) { 10 return ctors; 11 } 12 } 13 } 14 } 15 return null; 16 }
SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors()
第三次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors()---第三次執行后置處理器
1 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { 2 for (BeanPostProcessor bp : getBeanPostProcessors()) { 3 if (bp instanceof MergedBeanDefinitionPostProcessor) { 4 MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; 5 bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); 6 } 7 } 8 }
org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
1 public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { 2 InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); 3 metadata.checkConfigMembers(beanDefinition); 4 }
第四次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.getEarlyBeanReference()---第四次執行后置處理器
1 protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { 2 Object exposedObject = bean; 3 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 4 for (BeanPostProcessor bp : getBeanPostProcessors()) { 5 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { 6 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 7 exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); 8 } 9 } 10 } 11 return exposedObject; 12 }
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference()//解決循環依賴的
1 @Override 2 public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { 3 return bean; 4 }
第五次執行后置處理器:
代碼路徑:
org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.populateBean()--InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()---第五次執行后置處理器
1 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { 2 if (bw == null) { 3 if (mbd.hasPropertyValues()) { 4 throw new BeanCreationException( 5 mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); 6 } 7 else { 8 // Skip property population phase for null instance. 9 return; 10 } 11 } 12 13 // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the 14 // state of the bean before properties are set. This can be used, for example, 15 // to support styles of field injection. 16 boolean continueWithPropertyPopulation = true; 17 // ***第五次執行后置處理器*** 18 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 19 for (BeanPostProcessor bp : getBeanPostProcessors()) { 20 if (bp instanceof InstantiationAwareBeanPostProcessor) { 21 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 22 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 23 continueWithPropertyPopulation = false; 24 break; 25 } 26 } 27 } 28 } 29 30 if (!continueWithPropertyPopulation) { 31 return; 32 } 33 34 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); 35 36 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { 37 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); 38 // Add property values based on autowire by name if applicable. 39 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) { 40 autowireByName(beanName, mbd, bw, newPvs); 41 } 42 // Add property values based on autowire by type if applicable. 43 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { 44 autowireByType(beanName, mbd, bw, newPvs); 45 } 46 pvs = newPvs; 47 } 48 49 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); 50 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); 51 52 PropertyDescriptor[] filteredPds = null; 53 if (hasInstAwareBpps) { 54 if (pvs == null) { 55 pvs = mbd.getPropertyValues(); 56 } 57 for (BeanPostProcessor bp : getBeanPostProcessors()) { 58 if (bp instanceof InstantiationAwareBeanPostProcessor) { 59 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 60 // 61 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); 62 if (pvsToUse == null) { 63 if (filteredPds == null) { 64 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); 65 } 66 // ***第六次執行后置處理器*** 67 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 68 if (pvsToUse == null) { 69 return; 70 } 71 } 72 pvs = pvsToUse; 73 } 74 } 75 } 76 if (needsDepCheck) { 77 if (filteredPds == null) { 78 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); 79 } 80 checkDependencies(beanName, mbd, filteredPds, pvs); 81 } 82 83 if (pvs != null) { 84 applyPropertyValues(beanName, mbd, bw, pvs); 85 } 86 }
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation();
1 @Override 2 public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { 3 return true; 4 }
第六次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.populateBean()--InstantiationAwareBeanPostProcessor.postProcessPropertyValues()---第六次執行后置處理器
populateBean()//同上面第五次調用后置處理器
InstantiationAwareBeanPostProcessor.postProcessPropertyValues();
1 public PropertyValues postProcessPropertyValues( 2 PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { 3 4 return postProcessProperties(pvs, bean, beanName); 5 }
第七次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.initializeBean()--applyBeanPostProcessorsBeforeInitialization()--BeanPostProcessor.postProcessBeforeInitialization()---第七次執行后置處理器
1 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { 2 if (System.getSecurityManager() != null) { 3 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 4 invokeAwareMethods(beanName, bean); 5 return null; 6 }, getAccessControlContext()); 7 } 8 else { 9 invokeAwareMethods(beanName, bean); 10 } 11 12 Object wrappedBean = bean; 13 if (mbd == null || !mbd.isSynthetic()) { 14 //***第七次調用后置處理器*** 15 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 16 } 17 18 try { 19 invokeInitMethods(beanName, wrappedBean, mbd); 20 } 21 catch (Throwable ex) { 22 throw new BeanCreationException( 23 (mbd != null ? mbd.getResourceDescription() : null), 24 beanName, "Invocation of init method failed", ex); 25 } 26 if (mbd == null || !mbd.isSynthetic()) { 27 //***第八次調用后置處理器*** 28 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 29 } 30 31 return wrappedBean; 32 }
1 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) 2 throws BeansException { 3 4 Object result = existingBean; 5 for (BeanPostProcessor processor : getBeanPostProcessors()) { 6 Object current = processor.postProcessBeforeInitialization(result, beanName); 7 if (current == null) { 8 return result; 9 } 10 result = current; 11 } 12 return result; 13 }
第八次執行后置處理器:
代碼路徑:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
AbstractAutowireCapableBeanFactory.initializeBean()--applyBeanPostProcessorsAfterInitialization()--BeanPostProcessor.postProcessAfterInitialization()---第八次執行后置處理器
1 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 2 throws BeansException { 3 4 Object result = existingBean; 5 for (BeanPostProcessor processor : getBeanPostProcessors()) { 6 Object current = processor.postProcessAfterInitialization(result, beanName); 7 if (current == null) { 8 return result; 9 } 10 result = current; 11 } 12 return result; 13 }
第九次執行后置處理器:
bean銷毀的時候執行的后置處理器。
Spring執行BeanPostProcessor的時間和作用:
當一個bean實例化的過程中,首先會初始化bean的構造方法,然后執行BeanPostProcessor.postProcessBeforeInitialization()方法,然后執行添加@PostConstruct注解的方法,然后執行BeanPostProcessor.postProcessAfterInitialization()的方法。(spring-aop的實行原理)