我是靠谱客的博主 害怕冰棍,最近开发中收集的这篇文章主要介绍Spring底层原理(3)前言一、doCreateBean(),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 前言
  • 一、doCreateBean()
    • 1.BeanWrapper
      • 1.1.createBeanInstance()
    • 2.applyMergedBeanDefinitionPostProcessors
    • 3.earlySingletonExposure
    • 4.populateBean
      • 4.1.hasInstantiationAwareBeanPostProcessors
      • 4.2.依赖注入
        • 4.2.1.spring自带依赖注入
        • 4.2.2.@Autowired、@Resource 依赖注入
    • 5.initializeBean
    • 6.registerDisposableBeanIfNecessary


前言

提示:doCreateBean方法是spring创建Bean的重要过程

例如:这里将模块化介绍doCreateBean方法。


提示:以下是本篇文章正文内容,下面案例可供参考

一、doCreateBean()

代码如下(示例):

 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
      instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }

    if (instanceWrapper == null) {
      instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }

    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
    }

    synchronized(mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
        try {
          this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        } catch (Throwable var17) {
          throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
        }

        mbd.postProcessed = true;
      }
    }

    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if (earlySingletonExposure) {
      if (this.logger.isTraceEnabled()) {
        this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
      }

      this.addSingletonFactory(beanName, () -> {
        return this.getEarlyBeanReference(beanName, mbd, bean);
      });
    }

    Object exposedObject = bean;

    try {
      this.populateBean(beanName, mbd, instanceWrapper);
      exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable var18) {
      if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
        throw (BeanCreationException)var18;
      }

      throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
    }

    if (earlySingletonExposure) {
      Object earlySingletonReference = this.getSingleton(beanName, false);
      if (earlySingletonReference != null) {
        if (exposedObject == bean) {
          exposedObject = earlySingletonReference;
        } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
          String[] dependentBeans = this.getDependentBeans(beanName);
          Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
          String[] var12 = dependentBeans;
          int var13 = dependentBeans.length;

          for(int var14 = 0; var14 < var13; ++var14) {
            String dependentBean = var12[var14];
            if (!this.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.");
          }
        }
      }
    }

    try {
      this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
      return exposedObject;
    } catch (BeanDefinitionValidationException var16) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
    }
  }

这里我们将doCreateBean方法拆分一下

1.BeanWrapper

 BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
      instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }

    if (instanceWrapper == null) {
      instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }

    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
    }

这里涉及Bean推断构造方法。
由于spring启动的时候就可能需要把某些Bean创建出来了(factoryBean)
由上述代码可以看出BeanWrapper中可能获得Bean以及BeanType,相当于对Bean去进行了包装,所以createBeanInstance()会去推断构造方法

1.1.createBeanInstance()

先大致了解一下,后续专门来研究

 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
     throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
   } else {
     Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
     if (instanceSupplier != null) {
       return this.obtainFromSupplier(instanceSupplier, beanName);
     } else if (mbd.getFactoryMethodName() != null) { 
     //针对@Bean注解对应的BeanDefinition
       return this.instantiateUsingFactoryMethod(beanName, mbd, args);
     } else {
       boolean resolved = false;
       boolean autowireNecessary = false;
       if (args == null) {
         synchronized(mbd.constructorArgumentLock) {
           if (mbd.resolvedConstructorOrFactoryMethod != null) {
             resolved = true;
             autowireNecessary = mbd.constructorArgumentsResolved;
           }
         }
       }

       if (resolved) {
         return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
       } else {
       //遍历出所有的构造方法
         Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
         if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
           ctors = mbd.getPreferredConstructors();
           //有构造?用构造:无参构造
           return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
         } else {
           return this.autowireConstructor(beanName, mbd, ctors, args);
         }
       }
     }
   }
 }

2.applyMergedBeanDefinitionPostProcessors

 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    Iterator var4 = this.getBeanPostProcessorCache().mergedDefinition.iterator();

    while(var4.hasNext()) {
    //遍历出RootBeanDefinition
      MergedBeanDefinitionPostProcessor processor = (MergedBeanDefinitionPostProcessor)var4.next();
      processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
  }

代码如下(示例):


@Component
public class DemoRootBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
  @Override
  public void postProcessMergedBeanDefinition(RootBeanDefinition rootBeanDefinition, Class<?> aClass, String beanName) {
    if (beanName.equals("userService")) {
        rootBeanDefinition.setInitMethodName("aaa");
        rootBeanDefinition.getPropertyValues().add("orderService", new OrderService());
    }
  }
}

这里在userService里面加一个aaa方法,就会去调用,由于这里只是去实例化并没有去给属性赋值,因此我们这里其实也可以给属性赋值,我们在userService的类里面加入成员变量OrderService orderSerivce并且添加set方法在上述代码中加上
rootBeanDefinition.getPropertyValues().add(“orderService”, new OrderService());
然后我们启动发现orderService已赋上值
在这里插入图片描述

3.earlySingletonExposure

这里是处理循环依赖的,后续再研究

4.populateBean

属性填充

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 {
      if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
        Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();

        while(var4.hasNext()) {
          InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
          if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
          }
        }
      }

      PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
      int resolvedAutowireMode = mbd.getResolvedAutowireMode();
      if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
        MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
        if (resolvedAutowireMode == 1) {
          this.autowireByName(beanName, mbd, bw, newPvs);
        }

        if (resolvedAutowireMode == 2) {
          this.autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
      }

      boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
      boolean needsDepCheck = mbd.getDependencyCheck() != 0;
      PropertyDescriptor[] filteredPds = null;
      if (hasInstAwareBpps) {
        if (pvs == null) {
          pvs = mbd.getPropertyValues();
        }

        PropertyValues pvsToUse;
        for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
          InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
          pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
          if (pvsToUse == null) {
            if (filteredPds == null) {
              filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }

            pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
              return;
            }
          }
        }
      }

      if (needsDepCheck) {
        if (filteredPds == null) {
          filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }

        this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
      }

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

    }
  }

4.1.hasInstantiationAwareBeanPostProcessors

   if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
       Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();

       while(var4.hasNext()) {
         InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
         if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
           return;
         }
       }
     }

!mbd.isSynthetic()大部分情况下都是true,hasInstantiationAwareBeanPostProcessors所判断的是实例化后的方法
注意:实例化后和初始化前是不一样的object
原因:bean的生命周期中,逻辑是 实例化后->属性填充->初始化前
他们的区别在于实例化后的对象里面的属性是没值的,而初始化前里面有注入的成员属性是有值的。

4.2.依赖注入

4.2.1.spring自带依赖注入

这里是除开@Autowired、@Resource、@Inject、@Value,spring自带的依赖注入功能

PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
      int resolvedAutowireMode = mbd.getResolvedAutowireMode();
      if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
        MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
        if (resolvedAutowireMode == 1) {
          this.autowireByName(beanName, mbd, bw, newPvs);
        }

        if (resolvedAutowireMode == 2) {
          this.autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
      }

这里是直接调用spring自带的依赖注入

示例代码如下

@ComponentScan(basePackages = "com.example.spring")
public class AppConfig {
  @Bean(autowire = Autowire.BY_TYPE)
  public UserService userService(){
    return new UserService();
  }
}

并且在userService中加入setOrderService方法,就会在属性填充的时候把orderService注入到userService里面的成员变量orderService里面。
这里其实也是去利用BeanPostProcessor机制去实现这个功能,其实本质上来说也是去往spring容器里面注入了BeanPostProcessor的Bean然后去实现的本质上其实@Autowired、@Resource也是通过BeanPostProcessor来实现的。
其实大部分情况下不会走这里代码,因为我们基本不会用这种配置,因为这种功能太灵活了,这个Bean的类里面所有的set方法spring都会调用,Autowired注解这种比较好控制。

4.2.2.@Autowired、@Resource 依赖注入

   boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
      boolean needsDepCheck = mbd.getDependencyCheck() != 0;
      PropertyDescriptor[] filteredPds = null;
      if (hasInstAwareBpps) {
        if (pvs == null) {
          pvs = mbd.getPropertyValues();
        }
        PropertyValues pvsToUse;
        for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
          InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
            //这里把pvs带入进来是为了检验
             //假设在自己的PostProcessor去注入了值,那么在这里会跳过注入
             //直接用我们自己注入的值
          pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
          if (pvsToUse == null) {
            if (filteredPds == null) {
              filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
              pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
              return;
            }
          }
        }
      }

5.initializeBean

初始化

 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
      AccessController.doPrivileged(() -> {
        this.invokeAwareMethods(beanName, bean);
        return null;
      }, this.getAccessControlContext());
    } else {
      this.invokeAwareMethods(beanName, bean);
    }

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

    try {
    //初始化
      this.invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable var6) {
      throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
    }

    if (mbd == null || !mbd.isSynthetic()) {
    //初始化
      wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    //最终创建的Bean对象
    return wrappedBean;
  }

6.registerDisposableBeanIfNecessary

里面判断是否还有销毁的逻辑

最后

以上就是害怕冰棍为你收集整理的Spring底层原理(3)前言一、doCreateBean()的全部内容,希望文章能够帮你解决Spring底层原理(3)前言一、doCreateBean()所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部