通過BeanPostProcessor理解Spring中Bean的生命周期


通過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));
}
registerBeanPostProcessors

通過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;
}
doGetBean
  • 先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表示初始化。實例化的意思在對象還未生成,初始化的意思在對象已經生成

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM