通過BeanPostProcessor理解Spring中Bean的生命周期及AOP原理
Spring源碼解析(十一)Spring擴展接口InstantiationAwareBeanPostProcessor解析
Spring bean的生命周期

Spring作為一個優秀的框架,擁有良好的可擴展性。Spring對對象的可擴展性主要就是依靠InstantiationAwareBeanPostProcessor和BeanPostProcessor來實現的。
- InstantiationAwareBeanPostProcessor 主要是作用於實例化階段。
- BeanPostProcessor 主要作用與 初始化階段。
注冊BeanPostProcessor
InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:實例化。先區別一下Spring Bean的實例化和初始化兩個階段的主要作用:
1、實例化—-實例化的過程是一個創建Bean的過程,即調用Bean的構造函數,單例的Bean放入單例池中
2、初始化—-初始化的過程是一個賦值的過程,即調用Bean的setter,設置Bean的屬性
之前的BeanPostProcessor作用於過程(2)前后,現在的InstantiationAwareBeanPostProcessor則作用於過程(1)前后;
InstantiationAwareBeanPostProcessor接口繼承BeanPostProcessor接口,它內部提供了3個方法,再加上BeanPostProcessor接口內部的2個方法,所以實現這個接口需要實現5個方法。InstantiationAwareBeanPostProcessor接口的主要作用在於目標對象的實例化過程中需要處理的事情,包括實例化對象的前后過程以及實例的屬性設置
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }
applicationContext構造方法中調用refresh()方法
refresh() 方法中這里主要關心兩個放
- registerBeanPostProcessors(beanFactory); 注冊BeanPostProcessor
- finishBeanFactoryInitialization(beanFactory); 注冊余下的Singletions Bean
public void refresh() throws BeansException, IllegalStateException { // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); }
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
通過beanFactory.getBeanNamesForType來獲取所有BeanPostProcessor。
BeanPostProcessor按優先級分為PriorityOrdered,Ordered和其他的,對他們分別進行操作。
- 先beanFactory.getBean進性實例化,
- 再使用sortPostProcessors() 進行排序,
- 最后registerBeanPostProcessors()進行注冊。
BeanFactory.getBean()(注冊Bean)
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; //緩存 // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. //判斷循環引用,拋異常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); // this.beanDefinitionMap.containsKey(beanName); 就是判斷有沒有BeanDefinition if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 獲取bean的依賴,實例化bean前先實例化依賴。 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //創建實例 // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } } } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } } return (T) bean; }
- 先getSingleton()從緩存中獲取Bean,如果沒有則創建。
- 創建過程先檢查有無循環依賴,有則拋出異常。
- 實例化bean前先實例化所依賴的對象。
createBean,調用的開端
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } //省略.... Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; }
上面代碼里面看到,在執行doCreateBean之前有resolveBeforeInstantiation方法;doCreateBean是創建bean的方法;
resolveBeforeInstantiation是 判斷執行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation的接方法實現;
下面看看執行的依據:
執行 postProcessBeforeInstantiation方法的時機
/** * Apply before-instantiation post-processors, resolving whether there is a * before-instantiation shortcut for the specified bean. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return the shortcut-determined bean instance, or {@code null} if none */ protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; //如果beforeInstantiationResolved還沒有設置或者是false(說明還沒有需要在實例化前執行的操作) if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // 判斷是否有注冊過InstantiationAwareBeanPostProcessor類型的bean if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //執行 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); //只要有一個result不為null;后面的所有 后置處理器的方法就不執行了,直接返回(所以執行順序很重要) if (result != null) { return result; } } } return null; }
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); //如果返回null;后面的所有 后置處理器的方法就不執行,直接返回(所以執行順序很重要) if (result == null) { return result; } } return result; }
上面代碼說明:
如果postProcessBeforeInstantiation方法返回了Object是null;那么就直接返回,調用doCreateBean方法();
如果postProcessBeforeInstantiation返回不為null;說明修改了bean對象;然后這個時候就立馬執行postProcessAfterInitialization方法(注意這個是初始化之后的方法,也就是通過這個方法實例化了之后,直接執行初始化之后的方法;中間的實例化之后 和 初始化之前都不執行);
在調用postProcessAfterInitialization方法時候如果返回null;那么就直接返回,調用doCreateBean方法();(初始化之后的方法返回了null,那就需要調用doCreateBean生成對象了)
在調用postProcessAfterInitialization時返回不為null;那這個bean就直接返回給ioc容器了 初始化之后的操作 是這里面最后一個方法了;
通過上面的描述,我們其實可以在這里生成一個代理類:原文
postProcessAfterInstantiation調用的地方
代碼往后面執行走到了populateBean里面;這個主要是給bean填充屬性的;實例化已經在 pupulateBean之前已經完成了
//實例化bean;選擇不同策略來實例化bean instanceWrapper = createBeanInstance(beanName, mbd, args);
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { //省略。。。。 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //執行postProcessAfterInstantiation方法 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } //省略.... //下面的代碼是判斷是否需要執行postProcessPropertyValues;改變bean的屬性 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } //這里才是正在講 屬性值 真正的設置的我們的實例對象里面;之前postProcessPropertyValues這個還只是單純的改變PropertyValues //最后還是要通過PropertyValues 設置屬性到實例對象里面的 applyPropertyValues(beanName, mbd, bw, pvs); }
這個postProcessAfterInstantiation返回值要注意,因為它的返回值是決定要不要調用postProcessPropertyValues方法的其中一個因素(因為還有一個因素是mbd.getDependencyCheck());如果該方法返回false,並且不需要check,那么postProcessPropertyValues就會被忽略不執行;如果返回true,postProcessPropertyValues就會被執行
postProcessPropertyValues調用的地方
postProcessPropertyValues修改屬性,但是要注意postProcessAfterInstantiation返回true;
InstantiationAwareBeanPostProcessor總結
1. InstantiationAwareBeanPostProcessor接口繼承BeanPostProcessor接口,它內部提供了3個方法,再加上BeanPostProcessor接口內部的2個方法,所以實現這個接口需要實現5個方法。InstantiationAwareBeanPostProcessor接口的主要作用在於目標對象的實例化過程中需要處理的事情,包括實例化對象的前后過程以及實例的屬性設置
2. postProcessBeforeInstantiation方法是最先執行的方法,它在目標對象實例化之前調用,該方法的返回值類型是Object,我們可以返回任何類型的值。由於這個時候目標對象還未實例化,所以這個返回值可以用來代替原本該生成的目標對象的實例(比如代理對象)。如果該方法的返回值代替原本該生成的目標對象,后續只有postProcessAfterInitialization方法會調用,其它方法不再調用;否則按照正常的流程走
3. postProcessAfterInstantiation方法在目標對象實例化之后調用,這個時候對象已經被實例化,但是該實例的屬性還未被設置,都是null。因為它的返回值是決定要不要調用postProcessPropertyValues方法的其中一個因素(因為還有一個因素是mbd.getDependencyCheck());如果該方法返回false,並且不需要check,那么postProcessPropertyValues就會被忽略不執行;如果返回true,postProcessPropertyValues就會被執行
4. postProcessPropertyValues方法對屬性值進行修改(這個時候屬性值還未被設置,但是我們可以修改原本該設置進去的屬性值)。如果postProcessAfterInstantiation方法返回false,該方法可能不會被調用。可以在該方法內對屬性值進行修改
5. 父接口BeanPostProcessor的2個方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目標對象被實例化之后,並且屬性也被設置之后調用的
6. Instantiation表示實例化,Initialization表示初始化。實例化的意思在對象還未生成,初始化的意思在對象已經生成
