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

24 篇文章 17 订阅
22 篇文章 11 订阅

前言

在上一篇笔记中我们介绍了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过后就会调用,入口如下:
在这里插入图片描述

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

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

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

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

我们返回一个空的对象
在这里插入图片描述
所以这个时候是去执行了后面的逻辑的;所以我们可认为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 ...");
   }



}

在这里插入图片描述
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);
   }
}

这个方法的
在这里插入图片描述
代码片段就是调用了实例化之后的后置处理器,我们修改下之前的后置处理器,在Bml10BeanPostProcessor中实现一个实例化后的后置处理方法

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

   }
   return true;
}

在这里插入图片描述
请注意,这个方法是返回了一个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);
   }



}

在这里插入图片描述
所以如果你在实例化后的后置处理器中如果返回了false,那么你的这个bean的所有属性填充,依赖注入都是失效的,所以要多注意使用方法

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

在这里插入图片描述
@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会调用
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的这个声明周期的太多后置处理器,说实话,有点绕,不看到代码还有点记不清详细的顺序步骤,所以,我这里准备画一个图来把流程理清楚。

在这里插入图片描述

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值