SpringloC容器的依赖注入源码解析(5)—— doCreateBean之创建无属性的bean

 2023-01-26
原文作者:小王曾是少年 原文地址:https://juejin.cn/post/7032843832492294175

202301012058273281.png 上一篇文章分析到createBean执行到了doCreateBean方法:

202301012058277832.png 自定义的WelcomeController下面有一个成员变量WelcomeService被@Autowired标签标记

进入到doCreateBean方法里:

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
          throws BeanCreationException {
    
       // Instantiate the bean.
       // bean实例包装类
       BeanWrapper instanceWrapper = null;
       if (mbd.isSingleton()) {
          // 从未完成创建的包装Bean缓存中清理并获取相关中的包装Bean实例,毕竟是单例的,只能存一份
          instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
       }
       if (instanceWrapper == null) {
          //创建bean的时候,这里创建bean的实例有三种方法
          // 1.工厂方法创建
          // 2.构造方法的方式注入
          // 3.无参构造方法注入
          instanceWrapper = createBeanInstance(beanName, mbd, args);
       }
       final Object bean = instanceWrapper.getWrappedInstance();
       Class<?> beanType = instanceWrapper.getWrappedClass();
       if (beanType != NullBean.class) {
          mbd.resolvedTargetType = beanType;
       }
    
       // Allow post-processors to modify the merged bean definition.
       // 调用BeanDefinition属性合并完成后的BeanPostProcessor后置处理器
       synchronized (mbd.postProcessingLock) {
          if (!mbd.postProcessed) {
             try {
                // 被@Autowired、@Value标记的属性在这里获取
                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 {
          populateBean(beanName, mbd, instanceWrapper);
          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 " +
                         "'getBeanNamesOfType' 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;
    }

首先定义了一个包装类BeanWrapper

202301012058282323.png 该接口是spring提供的用于操作bean中属性的工具,使用它可以直接修改bean里面的属性,

202301012058286594.png BeanWrapperImplAbstractNestablePropertyAccessor的子类,BeanWrapper的实现类,通过父类使得其具有处理属性的能力。


回到doCreateBean,接下来判断BeanDefinition是否是单例,如果是的话尝试从缓存中获取FactoryBean实例,如果获取不到就会执行

    instanceWrapper = createBeanInstance(beanName, mbd, args);

进入到createBeanInstance里:

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
       // Make sure bean class is actually resolved at this point.
       Class<?> beanClass = resolveBeanClass(mbd, beanName);
       // 检查是否有权通过反射创建private的Class
       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());
       }
       // 使用工厂创建实例
       Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
       if (instanceSupplier != null) {
          return obtainFromSupplier(instanceSupplier, beanName);
       }
    
       // 如果工厂方法不为空,则使用工厂方法初始化策略
       if (mbd.getFactoryMethodName() != null) {
          return instantiateUsingFactoryMethod(beanName, mbd, args);
       }
    
       // Shortcut when re-creating the same bean...
       boolean resolved = false;
       boolean autowireNecessary = false;
       if (args == null) {
          synchronized (mbd.constructorArgumentLock) {
             // 如果已缓存的解析的构造函数或者工厂方法不为空,则可以利用构造函数解析
             // 因为需要根据参数确认底使用哪个构造函数
             if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
             }
          }
       }
       if (resolved) {
          // 自动注入,调用构造函数自动注入
          if (autowireNecessary) {
             return autowireConstructor(beanName, mbd, null, null);
          }
          else {
             // 使用默认构造函数构造
             return instantiateBean(beanName, mbd);
          }
       }
    
       // Candidate constructors for autowiring?
       // 使用带参的构造函数进行装配
       Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
       if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
             mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
          return autowireConstructor(beanName, mbd, ctors, args);
       }
    
       // Preferred constructors for default construction?
       ctors = mbd.getPreferredConstructors();
       if (ctors != null) {
          return autowireConstructor(beanName, mbd, ctors, null);
       }
    
       // No special handling: simply use no-arg constructor.
       // 使用默认的构造函数
       return instantiateBean(beanName, mbd);
    }

第一行会再次调用resolveBeanClass尝试去获取bean里面的class对象,之后看看class的访问修饰符,检查是否有权通过反射创建private的Class,如果bean使用了java自带的函数式接口Supplier,即工厂方法,就会调用工厂方法里的get方法来创建bean实例

    @FunctionalInterface
    public interface Supplier<T> {
    
        /**
         * Gets a result.
         *
         * @return a result
         */
        T get();
    }

这里我们没有用到Supplier,就会看一下BeanDefinition里有没有定义Spring里的工厂方法,如果有则通过factory-method来返回实例。

如果不是上述两种方式,如果传入的args参数为空就会来到synchronized代码块,先判断一下先前解析配置成BeanDefinition实例的时候,有没有获取到已经解析的构造函数,如果有就会调用

    return autowireConstructor(beanName, mbd, null, null);

进行有参构造函数的解析。

之后会使用带参的构造函数进行装配或者无参的构造函数进行装配。

    return instantiateBean(beanName, mbd);

进入到调用无参构造函数的方法里:

    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
       try {
          Object beanInstance;
          final BeanFactory parent = this;
          if (System.getSecurityManager() != null) {
             beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                   getInstantiationStrategy().instantiate(mbd, beanName, parent),
                   getAccessControlContext());
          }
          else {
             //使用指定的策路模式来初始化实例,默认用的是SimplelnstantiationStrategy的cglib方法
             beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
          }
          BeanWrapper bw = new BeanWrapperImpl(beanInstance);
          initBeanWrapper(bw);
          return bw;
       }
       catch (Throwable ex) {
          throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
       }
    }

instantiate默认调用的是SimpleInstantiationStrategy类中的方法,在方法里会首先判断是否有look-up method等使用其他bean的替换方法的情况,如果有的话会使用cglib重写bean原本的方法,没有的话会制定同步代码块

    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
       // Don't override the class with CGLIB if no overrides.
       // 如果Bean定义里面的方法没有被覆盖,则不需要CGLUB来重写
       if (!bd.hasMethodOverrides()) {
          Constructor<?> constructorToUse;
          synchronized (bd.constructorArgumentLock) {
             // 获取对象的构造方法或工厂方法
             constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
             if (constructorToUse == null) {
                //使 用反射机制获取Bean的类,看看是否是接口
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
                   throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                   if (System.getSecurityManager() != null) {
                      constructorToUse = AccessController.doPrivileged(
                            (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                   }
                   else {
                      constructorToUse = clazz.getDeclaredConstructor();
                   }
                   bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                   throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
             }
          }
          // 使用BeanUtils,最终调用newInstance方法通过反射来获取实例
          return BeanUtils.instantiateClass(constructorToUse);
       }
       else {
          // Must generate CGLIB subclass.
          return instantiateWithMethodInjection(bd, beanName, owner);
       }
    }

再回到instantiateBean方法,获取到了创建好的bean实例之后,就会将其包装到BeanWrapper里,包装好了之后还回去初始化

202301012058290385.png

    protected void initBeanWrapper(BeanWrapper bw) {
       bw.setConversionService(getConversionService());
       registerCustomEditors(bw);
    }

initBeanWrapper主要是给wrapper设定上自定义类型转换工具

instantiateBean最终创建好的beanWrapper,此时就完成了createBeanInstance的调用。


回到doCreateBean,此时就会将创建好的instanceWrapper的bean实例类型传入到applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);