欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring bean生命周期之doCreateBean方法详解

程序员文章站 2022-07-10 18:31:35
Spring bean声明周期之doCreateBean方法详解前言@ValuecreateBean方法详解实例化前方法调用实例化前初始化后doCreateBeanapplyMergedBeanDefinitionPostProcessors填充属性&实例化后(populateBean)@AutoWired的实现逻辑&属性填充后的后置处理器初始化BeaninitializeBean初始化前后置处理器初始化方法前言在上一篇笔记中我们介绍了bean的初始化声明周期,但是期间有个最核心的方法c...

前言

在上一篇笔记中我们介绍了bean的初始化声明周期,但是期间有个最核心的方法createBean没有讲,这个方法是如果在创建bean的过程中,没有找到对应的ban对象,那么最后就会调用createBean方法,createBean方法中包含了很多bean实例化和初始化、aware的调用以及spring内置的一些beanPostProcessor方法调用的一些过程,可以算是最核心的方法,我认为的是在spring的声明周期中 ,这个方法算是比较重要的,也是比较绕的,在spring的ioc容器中,我觉得是分为三个比较重要的部分,第一个部分就是通过asm技术扫描类的全限定名到BeanDefinition中的beanclass中,第二个主要的过程就是BeanFactoryPostProcessor的后置处理器,也就是bean工厂的后置处理器,第三个过程就是bean的BeanPostProcessor,bean后置处理器,特别是beanPostProcessor里面有很多spring内置的bean后置处理器,比如bean的实例化前、实例化、实例化后,属性填充后、初始化前、初始化、初始化后这些过程都是bean的后置处理器去完成的,当然了我们也根据编写自己的后置处理器,自己编写的后置处理器只需要继承spring的beanPostProcessor或者其他继承了BeanPostProcessor后置处理器就可实现了,所以spring在上面的6个过程中调用的后置处理器都会执行,就是程序员自己定义的后置处理器和spring内部的后置处理器都要执行,所以spring的bean后置处理器非常重要,也是spring的扩展点之一,我们熟知的大名鼎鼎的Spring Aop也就是使用了spring的Bean后置处理器,Spring AOP是在spring初始化完成后调用的后置处理器,也就是初始化后的后置处理器,这个后面有时间再记录,今天主要记录下spring的createBean方法,也就是大量的后置处理器来了,createBean方法的入口是在geBean的时候,如果经过一系列的方法都没有找到对应的Bean过后就会调用,入口如下:
Spring bean生命周期之doCreateBean方法详解

@Value

在讲解createBean方法之前,我们来看一个很有意思的东西,可能大部分都不知道,就是我们在一个bean中声明了另外一个bean,通常一般的做法是通过@AutoWired来进行注入的,但是有没有人是否知道其实还可以通过@Value来注入的,比如:

@Component
public class UserService {

   @Value("#{orderService}")
   private OrderService orderService;

   @Autowired
   private OrderService orderService1;


   public void test(){
      System.out.println("@Value="+orderService);
      System.out.println("@AutoWried="+orderService1);
   }

}

输出的是:
@Value=com.bml10.service.OrderService@28864e92
@AutoWried=com.bml10.service.OrderService@28864e92

所以通过@Value也可以进行注入的,但是要注意@Value的注入方式和@AutoWried是不对等的,@Value是直接去单例池给你找到注入进去,而@AutoWired是先byType,再byName的,而且还要注意的是@Value中如果直接使用的是字符串,那么就会将这个字符串直接注入到属性上,如果是$占位符,那么就会获取Environment中的属性参数赋值过去,只有表达式是#,el表达式,spring才会从单例池中获取bean对象进行注入。

createBean方法详解

我这边现在直接上我在源码中编写的注释和源码,如下

/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 * @see #doCreateBean
 * 这个方法特别复杂,是spring容器创建bean和获取Bean的核心方法
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isTraceEnabled()) {
      logger.trace("Creating instance of bean '" + beanName + "'");
   }
   //到这个方法创建Bean的时候beanDefinition的类型必须是RootBeanDefinition
   //RootBeanDefinition是*的父类BeanDefinition,是不允许再有父亲的BeanDefinition的
   //在调用这个方法之前,是会进行BeanDefinition的封装和合并的
   RootBeanDefinition mbdToUse = mbd;

   // Make sure bean class is actually resolved at this point, and
   // clone the bean definition in case of a dynamically resolved Class
   // which cannot be stored in the shared merged bean definition.
   //加载beanclass,将bean的class拿出来加载到jvm中
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      //加载成功过后,然后创建一个对象RootBeanDefinition,这个RootBeanDefinition就是最终创建的单例对象放入到单例池
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      //上面的的英文是官方解释:给一个创建一个代理对象bean的机会在bean的后置处理器中
      //简单来说就是这里是提供给程序员实现的方法,比如你想代理一些bean,那么你就可以实现相关的后置处理器
      //比如aop,或者你想为一些bean添加一些职责,那么只要返回不为空,spring就不会为你创建bean了,会直接用你创建的bean
      //这个方法可以叫做bean的实例化前,可以简单这样理解
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      //这个创建bean是spring容器自带的创建bean,也就是代码走到这里,则证明需要spring来创建bean了
      //一般在spring项目中,普通的bean一般都会在这里由spring来创建,而特殊的Bean可能在上面由resolveBeforeInstantiation
      //来直接创建了
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

针对上面的方法,有些地方需要做一个demo来验证,也是对其的理解更加的深刻,我们研究creaeBean是根据实例化前、实例化、实例化后、填充属性、填充属性后、调用aware、初始化前、初始化、初始化后的顺序来讲解,我们先来看下实例化前,也就是上面的方法Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

实例化前方法调用

/**
 * 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
 * 这个方法其实就是调用bean的后置处理器,bean的后置处理器有点多,分为
 * 实例化前、实例化后、调用aware后、初始化前、初始化后
 * 而下面这个方法就是在bean的实例化之前调用的,而这个方法是返回一个对象
 * 所以如果说你这个方法调用完毕过后,返回的一个对象不为空,那么就说明你的bean已经存在了,已经有了
 * 那么就不会在调用你后面的调用aware就是不会再调用spring提供的创建Bean的方法了
 * 但是如果applyBeanPostProcessorsBeforeInstantiation返回的对象不为空,那么spring还猜想你可能还有
 * 实例化的一些操作,所以这里还要调用那个实例化后的bean后置处理器applyBeanPostProcessorsAfterInitialization
 * 按正常的逻辑,spring会通过实例化前、实例化后、调用aware后、初始化前、初始化后来调用后置处理器,但是下的这个方法
 * 是你人为的干预了spring的实例化和初始化,那么你既然实例化了,那么就自己去调用初始化后的一些后置处理器,
 * 请注意,这个方法也不会调用后面的aware方法了
 */
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            //applyBeanPostProcessorsBeforeInstantiation是调用的bean的实例化的后置处理器
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               //如果返回的bean不为空,则证明spring不会去调用它自己的createBean方法了,因为你返回了对象
               //所以下面还要看你有没有自己的bean初始化后的逻辑,如果有就调用,所以卫生么这个方法有
               //bean的实例化前的方法和bean初始化后的方法
               //applyBeanPostProcessorsAfterInitialization是调用的bean的初始化后置处理器
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

看上面的代码逻辑,其实就是调用了初始化前,实例化后,如果调用了实例化前的方法已经返回了一个对象了,那么也就是说不用再调用spring后面的一些过程了,就直接是一个可用的对象了,也就是没有办法调用后面的实例化后,初始化以及aware等方法了,spring的设计就是这样的,但是为了使功能更加完善一点,如果调用实例化前的方法
applyBeanPostProcessorsBeforeInstantiation,如果这个时候返回一个不为空的对象,那么就意味着不用调用spring后面的方法,所以这个时候可以再调用自己实现的初始化后的后置处理方法applyBeanPostProcessorsAfterInitialization

实例化前

@Nullable
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);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

看上面的过程可以知道获取了系统中的所有后置处理器,然后循环调用,如果这个后置处理器实现了InstantiationAwareBeanPostProcessor,那么调用实例化前的后置处理方法postProcessBeforeInstantiation

初始化后

/**
 *  这个后置处理器的方法是bean初始化后的方法,请注意,这个方法要懂,否则可能你的初始化会出一些问题
 *  这个方法的意思就是获取到系统中的所有bean后置处理器,如果调用任何一个处理器返回了null,那么就直接返回了
 *  原有的对象,也就不会再去执行后续的@PostConstruct的方法了
 *  这个方法的 意思就是每一个bean都要去调用下系统中存在的后置处理器,比如系统中有4个后置处理器,
 *  如果其中一个后置处理器返回null,那么这个工序就不会走下去了,就会直接返回了
 * @param existingBean the existing bean instance
 * @param beanName the name of the bean, to be passed to it if necessary
 * (only passed to {@link BeanPostProcessor BeanPostProcessors};
 * can follow the {@link #ORIGINAL_INSTANCE_SUFFIX} convention in order to
 * enforce the given instance to be returned, i.e. no proxies etc)
 * @return
 * @throws BeansException
 */

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

这个后置处理器的方法是bean初始化后的方法,请注意,这个方法要懂,否则可能你的初始化会出一些问题, 这个方法的意思就是获取到系统中的所有bean后置处理器,如果调用任何一个处理器返回了null,那么就直接返回了原有的对象,也就不会再去执行后续的@PostConstruct的方法了
这个方法的 意思就是每一个bean都要去调用下系统中存在的后置处理器,比如系统中有4个后置处理器, 如果其中一个后置处理器返回null,那么这个工序就不会走下去了,就会直接返回了。

我们来写一个自己的bean后置处理器


@Component
public class Bml10BeanPostProcessor implements InstantiationAwareBeanPostProcessor {


   @Override
   public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

      if(beanName.equals("orderService")){
         System.out.println("OrderService 实例化前");

         return new OrderService();
      }
      return null;
   }

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

      if(beanName.equals("orderService")){
         System.out.println("OrderService 初始化后");
      }
      return bean;
   }
}


@Component
public class OrderService {

   @PostConstruct
   public void init(){
      System.out.println("orderService init ...");
   }
}

看上面的代码,我们的程序输出应该是
OrderService 实例化前
orderService init …
OrderService 初始化后
这个顺序才对,但是我们看输出的结果如下:
Spring bean生命周期之doCreateBean方法详解
也就是说我们的初始化方法init没有执行,为什么呢?如果理解上面我在源码上写的注释就明白了,@PostConstruct是spring内置的初始化方法,也可以被叫做生命周期初始化回调方法,但是我们在执行Bml10BeanPostProcessor 后置处理器的时候,把orderService直接new出来返回了,那么这个时候就没有到后面的spring初始化前的后置方法,所以是不会执行的,@PostConstruct是在后置处理器
CommonAnnotationBeanPostProcessor中调用的,CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,所以执行初始化的@PostConstruct注解的方法是在InitDestroyAnnotationBeanPostProcessor中执行的,而上面的代码是在执行实例化就返回了一个对象了,则根本就不会走spring的下流程了,所以也就是为什么没有执行init方法,因为根本没有这块逻辑了,我们可以回忆看下上面的代码的实例化前返回对象的判断如下:
Spring bean生命周期之doCreateBean方法详解
如果不为就直接返回了你实例化返回的对象,为了证明这块逻辑,我们修改下自己的后置处理器

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

   if(beanName.equals("orderService")){
      System.out.println("OrderService 实例化前");

      //return new OrderService();
   }
   return null;
}

我们返回一个空的对象
Spring bean生命周期之doCreateBean方法详解
所以这个时候是去执行了后面的逻辑的;所以我们可认为resolveBeforeInstantiation这个方法是spring提供给程序员去扩展的,如果你的一个对象不想让spring来给你实例化和初始化,比如我们自己通过接口代理的一个对象就可以设置一个bean后置处理器,自己去创建一个代理对象出来,不用spring给我们实例化,场景很多,根据自己业务场景去使用。

doCreateBean

这个方法里面们包含了太多的bean生命周期的步骤,比如bean的实例化后、bean的实例化、bean的aware方法的调用、初始化、依赖注入,属性填充等步骤,这篇笔记主要记录下bean的实例化和初始化等一些后置处理器,所以其他先略过,后面会一一去记录所有的过程

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   /**
    * 下面的代码开始对bean实例化
    */
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }

   if (instanceWrapper == null) {
      //bean的实例化,里面包含了推断构造方法,简单来说就是对bean进行实例化,这个方法后面来将
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            //spring提供的又一个bean后置处理器,就是在bean实例化完成过后,可以进行调用
            //这个后置处理器可以传入指定的BeanDefinition,也就是你可以改变BeanDefinition的属性
            //但是这个时候bean都已经实例化完成了,就算你修改了beanclass也没有用了
            //但是有些属性我们还是可以设置的,比如可以手动设置初始化的方法mbd.setInitMethodName
            //@AutoWired注解的切入点就是在这个后置处理器中找到的并且注入到缓存中
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }

   // Eagerly cache singletons to be able to resolve circular references
   // even when triggered by lifecycle interfaces like BeanFactoryAware.
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      if (logger.isTraceEnabled()) {
         logger.trace("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      //和循环依赖有关,后面讲
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {

      /**
       * 填充属性,处理@AutoWried,调用bean的实例化后的方法
       */
      populateBean(beanName, mbd, instanceWrapper);
      /**
       * 这个方法是调用bean的初始化方法的
       */
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }

   //下面是依赖注入的代码,这个后面说
   if (earlySingletonExposure) {
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
            if (!actualDependentBeans.isEmpty()) {
               throw new BeanCurrentlyInCreationException(beanName,
                     "Bean with name '" + beanName + "' has been injected into other beans [" +
                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                     "] in its raw version as part of a circular reference, but has eventually been " +
                     "wrapped. This means that said other beans do not use the final version of the " +
                     "bean. This is often the result of over-eager type matching - consider using " +
                     "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
            }
         }
      }
   }

   // Register bean as disposable.
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}

applyMergedBeanDefinitionPostProcessors

/**
 * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
 * invoking their {@code postProcessMergedBeanDefinition} methods.
 * @param mbd the merged bean definition for the bean
 * @param beanType the actual type of the managed bean instance
 * @param beanName the name of the bean
 * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
 * 这个方法我个人的理解是可以被叫做合并bean过后的bean后置处理器
 * @AutoWired注解和@Value以及@Inject注解都是在这个后置处理器中实现的
 * 具体的后置处理器是AutowiredAnnotationBeanPostProcessor,在里面调用了postProcessMergedBeanDefinition
 */
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof MergedBeanDefinitionPostProcessor) {
         MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
         bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
      }
   }
}

这个bean的后置处理器是在spring实例化之前方法调用过后,bean开始实例化,bean实例化后过后调用的一个合并bean的后置处理,请注意,这个不是bean的实例化后的后置处理器,所有代码到这里的调用顺序是:bean实例化前后置处理->bean实例化->合并bean后置处理->bean实例化后后置处理
但是这个后置处理我们注意看它的参数就知道,它不是把你实例化得到的bean对象传入的,而是传入的RootBeanDefinition,那么我们想一下这个时候如果你传入的是BeanDefinition,那么你修改了BeanDefinition,还起作用吗?实际上这个时候bean以及实例化了,你修改了beanclass也没有用,但是总有业务场景可以使用到,就是你可以介入spring的实例化后过程,想加自己的业务逻辑,但是这里我们可以想到的是它本身可以在BeanDefinition中设置初始化方法,也就是initMethod,比如看下面的例子

@Component
public class Bml10MergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
   @Override
   public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {

      if(beanName.equals("orderService")){
         beanDefinition.setInitMethodName("margedInit");
      }

   }
}
@Component
public class OrderService {

   @PostConstruct
   public void init(){
      System.out.println("orderService init ...");
   }

   public void margedInit(){
      System.out.println("margedInit init ...");
   }



}

Spring bean生命周期之doCreateBean方法详解
OrderService中的两个初始化方法都已经调用了,一个是通过注解@PostConstruct来实现的,一个是我们通过后置处理器MergedBeanDefinitionPostProcessor 来添加的,添加的位置是在bean的实例化之后添加的,那么总有一个地方去调用,我们先记着这个点,下面会讲解在哪里调用的,而且是在@PostConstruct之后调用的

填充属性&实例化后(populateBean)

/**
 * Populate the bean instance in the given BeanWrapper with the property values
 * from the bean definition.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @param bw the BeanWrapper with bean instance
 *           这个方法是填充属性的方法,但是在这个方法里面调用了Bean的后置处理器实例化后,因为实例化前在前面调用,这里调用的是
 *           实例化后
 */
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   if (bw == null) {
      if (mbd.hasPropertyValues()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   //这里是调用实例化后的后置处理器
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               return;
            }
         }
      }
   }
   /**
    * 下面的这段逻辑处理的是@AutoWired,后面在说
    */
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   PropertyDescriptor[] filteredPds = null;
   if (hasInstAwareBpps) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      /**
       * 这里调用的又是bean的后置处理器,这里的后置处理器是在bean属性填充过后的bean后置处理器
       * 这个后置处理器正在现在用的最多,spring内部定义的InstantiationAwareBeanPostProcessor实现了这个接口,主要处理的是
       * @AutoWired的后置处理器,依赖注入的在这里调用的,最重要的是postProcessProperties这个方法
       * 所以InstantiationAwareBeanPostProcessor的后置处理器方法postProcessProperties是处理@AutoWired @Resource注解的
       * 这个方法后面讲
       */
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               if (filteredPds == null) {
                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
               }
               pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvsToUse == null) {
                  return;
               }
            }
            pvs = pvsToUse;
         }
      }
   }
   if (needsDepCheck) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }

   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

这个方法的
Spring bean生命周期之doCreateBean方法详解
代码片段就是调用了实例化之后的后置处理器,我们修改下之前的后置处理器,在Bml10BeanPostProcessor中实现一个实例化后的后置处理方法

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
   if(beanName.equals("orderService")){
      System.out.println("OrderService 实例化后");

   }
   return true;
}

Spring bean生命周期之doCreateBean方法详解
请注意,这个方法是返回了一个booelan的所以如果返回false的话,那么这个方法的后面的逻辑就不会执行了,也就是你的bean里面的比如你试下了ApplicationContextAware,那么后面的就不会执行了,比如:

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
   if(beanName.equals("orderService")){
      System.out.println("OrderService 实例化后");

   }
   return false;
}

@Component
public class OrderService {

   @Autowired
   private UserService userService;

   @PostConstruct
   public void init(){
      System.out.println("orderService init ...");
   }

   public void margedInit(){
      System.out.println("margedInit init ...");
   }

   public void tests(){
      System.out.println("userService="+userService);
   }



}

Spring bean生命周期之doCreateBean方法详解
所以如果你在实例化后的后置处理器中如果返回了false,那么你的这个bean的所有属性填充,依赖注入都是失效的,所以要多注意使用方法

@AutoWired的实现逻辑&属性填充后的后置处理器

Spring bean生命周期之doCreateBean方法详解
@AutoWired中的逻辑也是在InstantiationAwareBeanPostProcessor这个后置处理器中实现的,当然了你也可以实现这个后置处理器,但是spring内部有自己的后置处理器专门来处理依赖注入的逻辑的后置处理器,具体的后置处理器是
CommonAnnotationBeanPostProcessor,这个后面记录依赖注入的时候再来讲。

初始化Bean

exposedObject = initializeBean(beanName, exposedObject, mbd)这段逻辑就是初始化bean的,这个方法里面包含了spring内置的aware方法的调用,初始化前方法的调用、初始化后的方法调用,BeanDefinition中的初始化方法的调用,程序员实现了Aware方法的调用等

initializeBean

/**
 * Initialize the given bean instance, applying factory callbacks
 * as well as init methods and bean post processors.
 * <p>Called from {@link #createBean} for traditionally defined beans,
 * and from {@link #initializeBean} for existing bean instances.
 * @param beanName the bean name in the factory (for debugging purposes)
 * @param bean the new bean instance we may need to initialize
 * @param mbd the bean definition that the bean was created with
 * (can also be {@code null}, if given an existing bean instance)
 * @return the initialized bean instance (potentially wrapped)
 * @see BeanNameAware
 * @see BeanClassLoaderAware
 * @see BeanFactoryAware
 * @see #applyBeanPostProcessorsBeforeInitialization
 * @see #invokeInitMethods
 * @see #applyBeanPostProcessorsAfterInitialization
 *
 * 调用顺序是先
 * 1.调用spring内部的aware方法
 * 2.bean的初始化前的后置处理器
 * 3.bean的初始化方法调用
 * 4.bean的初始化后的方法调用
 */
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      //调用默认的aware方法
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
      if (mbd == null || !mbd.isSynthetic()) {
         //初始化前后置处理器
         wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
      }

      try {
         //调用初始化方法,InitializingBean中的初始化方法或者BeanDefinition中设置的初始化方法
         invokeInitMethods(beanName, wrappedBean, mbd);

      }
      catch (Throwable ex) {
         throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      //初始化后后置处理器
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

调用spring内置的aware,分了三类:
1.如果你的bean实现了BeanNameAware,那么就会当前的beanName回调给你;
2.如果你的bean实现了BeanClassLoaderAware,那么spring会把当前的spring类加载器回调给你;
3.如果你实现了BeanFactoryAware,那么spring会把bean工厂回调给你。

上面的aware是spring内置的aware,我感觉都非常有用,特别是bean工厂这个功能特别强大,简单来说就是有了工厂bean,我们能干很多事儿。但是不知道看客的你是否有注意到,我们平时使用的一个aware,ApplicationContextAware在这里没有呢?ApplicationContextAware这个aware更强大,可以得到spring的上下文,也就是拥有了所有,但是我们一般获取整个是用来获取bean比较多一点,就是在一些没有加入容器的类中可以通过一个容器中bean实现了ApplicationContextAware来获取bean,但是这个bean在哪里实现的呢?在bean初始化的后置处理器调用的,下面会说。

初始化前后置处理器

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   /**
    * 这个方法是调用spring的初始化前的后置处理器,请注意这里的代码逻辑
    * 比如这里有4个后置处理器,你自己写的类实现了这个后置处理器,不要反返回null
    * 因为bean对象已经给你了,如果你返回了null,那么则后面的后置处理器都不会执行了,看
    * if条件可知,你局当成这是一个工序,每一个工序都依赖于前一个工序,如果前一个工序告诉你没有货物了,
    * 那么下面的工序也没有办法走了,这个和初始前的后置处理器处理的方案是一模一样的
    *
    */
   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

初始化前的后置处理器,这个处理器有意思的,就是系统中的后置处理器,但凡任何一个后置处理器返回了null,那么就直接返回原bean对象,后面的后置处理器就不会执行了

@PostConstruct就是在这个后置处理器中调用的;而ApplicationContextAware也是在这个后置处理器中调用的,也就是初始化前的后置处理器,这个后置处理器中有两个spring内置的处理器:
InitDestroyAnnotationBeanPostProcessor:处理@PostConcustruct
ApplicationContextAwareProcessor:处理程序员自定义的Aware,比如ApplicationContextAware,还有很多,比如下面的截图:
Spring bean生命周期之doCreateBean方法详解
所以初始化前我们知道spring会调用
1.程序员实现了Aware接口
2.@PostConstruct初始化方法
3.程序员实现的postProcessBeforeInitialization后置处理器方法

初始化方法

invokeInitMethods(beanName, wrappedBean, mbd);
这个方法全部是初始化方法的调用,分为:
1.实现了InitializingBean的方法调用afterPropertiesSet()方法;
2.BeanDefinition中设置的initMethod方法,也是初始化方法

/**
 * Give a bean a chance to react now all its properties are set,
 * and a chance to know about its owning bean factory (this object).
 * This means checking whether the bean implements InitializingBean or defines
 * a custom init method, and invoking the necessary callback(s) if it does.
 * @param beanName the bean name in the factory (for debugging purposes)
 * @param bean the new bean instance we may need to initialize
 * @param mbd the merged bean definition that the bean was created with
 * (can also be {@code null}, if given an existing bean instance)
 * @throws Throwable if thrown by init methods or by the invocation process
 * @see #invokeCustomInitMethod
 * 这个是spring的初始化方法,其实就是调用bean的初始化方法,这个方法的初始化方法有两个地方,第一个是实现了InitializingBean的初始化方法
 * 第二个是在BeanDefinition中设置了initMethod方法,而已可以在这里调用
 */
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 (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         //调用InitializingBean类中的初始化的方法
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   /**
    * 下面是调用BeanDefinition中设置的initMethod方法,也是初始化方法
    */
   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);
      }
   }
}

这个初始化方法简单,这里就不说了,我们最上面说的实现了MergedBeanDefinitionPostProcessor 的用BeanDefinition设置了一个initMethod在哪里调用的,其实就是在这里调用的。
初始化后后置处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)这个是spring bean生命周期的最后一步了,就是bean初始化完成了,最后执行生命周期初始化后的后置处理器,这个方法在实例化前返回了不为空的bean对象已经说过了。这里就不说了,spring的这个声明周期的太多后置处理器,说实话,有点绕,不看到代码还有点记不清详细的顺序步骤,所以,我这里准备画一个图来把流程理清楚。

Spring bean生命周期之doCreateBean方法详解

本文地址:https://blog.csdn.net/scjava/article/details/109271899