> 文章列表 > 《Spring系列》第9章 Bean的加载(二) createBean()

《Spring系列》第9章 Bean的加载(二) createBean()

《Spring系列》第9章 Bean的加载(二) createBean()

前言

在上一章的doGetBean()中,介绍了创建Bean前的各种处理,那么具体实例化Bean的功能则调用createBean(),该方法AbstractAutowireCapableBeanFactory类重写,下面来解读一下源码:

一、createBean()

该方法大体步骤如下:

  1. 根据bean定义信息和bean名称解析得到bean的Class类型
  2. 验证并准备为此 bean 定义的方法覆盖,对应bean中的lookup-method + replaced-method2个属性【不好维护,平常少用,特殊情况使用】
  3. InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例;
  4. 执行真正创建bean的方法 ==> doCreateBean()
  5. 返回创建好的bean实例;
	@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// <1> 解析Class类型Class<?> resolvedClass = resolveBeanClass(mbd, beanName);// 特殊判断// 在下面会判断一个属性:BeanDefinition中的beanClass, 看着是存储Class,但实际进去,它是一个Object类型// 主要针对注解和XML两种定义方式,注解肯定就正常了,直接把类Class存进去,但是XML的方式,我们是定义一个Class属性,存储的是字符串// 这里这么多判断就是为了确定已经解析了Beanif (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {// 这里克隆1份,官方给出的英文注释:克隆 bean 定义以防动态解析的 Class 无法存储在共享的合并 bean 定义中mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {// <2> 验证即准备覆盖的方法,用的很少,用于处理lookup-method和replaced-method2个属性// 【很少用,不好维护】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.// <3> 给BeanPostProcess一个机会来返回代理对象,来替代真实的实例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 {// <4> 进行常规bean的创建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);}}

1.resolveBeanClass() 解析Class

整体方法的逻辑很简单

  1. 如果通过该BeanDefinition创建过实例,那么其中肯定会有存储,例如多例的Bean
  2. 如果是第一次创建,那么会通过Class.forName创建Class类型,然后存储到BeanDefinition
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)throws CannotLoadBeanClassException {try {// 1.如果已经解析过,则直接返回使用if (mbd.hasBeanClass()) {return mbd.getBeanClass();}// 判单是否有安全管理器if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());}else {// 2.代表第一次解析// 没有详细解读具体源码, 最底层就是通过JDK原生方法Class.forName(),根据类名来获取Class对象return doResolveBeanClass(mbd, typesToMatch);}}catch (PrivilegedActionException pae) {ClassNotFoundException ex = (ClassNotFoundException) pae.getException();throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (ClassNotFoundException ex) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (LinkageError err) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);}
}

2.resolveBeforeInstantiation()

实例化bean之前,判断是否应用后置处理器

@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) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;
}

二、doCreateBean()

执行步骤

  1. 单例,则首先尝试从【未完成的FactoryBean实例缓存】获取

  2. 【Bean实例化】。可以通过4种方式来实例化

  3. 扩展机制:MergedBeanDefinitionPostProcessor后置处理器的应用,允许它修改RootBeanDefinition

  4. 是否允许提前暴露bean对象,用于解决循环依赖问题,暴露方式为加入三级缓存

  5. 【Bean属性填充】

  6. 【Bean初始化

  7. 如果允许早期暴露,需要进行循环依赖检查

  8. 注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理;

  9. 完成bean的创建并返回

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;// <1> 单例,则首先尝试从【未完成的FactoryBean实例缓存】获取if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// <2>【Bean实例化】if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}// <3> 获取Bean对象和ClassObject bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.// <4> 允许后处理器修改合并的 bean 定义。synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {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.// <5> 是否提前暴漏 = 单例bean && 配置允许提前暴暴露 && 当前bean正在创建中(如果都没有开始创建往缓存加个球)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");}// 为避免后期循环依赖, 可以在bean初始化完成前将创建实例的ObjectFactory加入工厂addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {// <6>【Bean属性注入】,可能存在依赖于其它bean的属性,则会递归初始化依赖的beanpopulateBean(beanName, mbd, instanceWrapper);// <7>【Bean初始化】初始化Bean,如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等等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);}}// <8> 特殊判断, 为了解决AOP情况下的循环依赖if (earlySingletonExposure) {// 从三级缓存获取, 如果为空则代表普通Bean, 有值则代表存在循环依赖Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {// 初始化Bean方法中,没有把Bean引用改变if (exposedObject == bean) {// 这为了解决的问题,如果经过循环依赖以后,A已经创建了代理对象,这里会替换把A替换成代理对象返回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);}}// 因为bean创建后其所依赖的bean一定是已经创建的// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在循环依赖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 {// <9> 注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、// 实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}// <10> 完成bean的创建并返回return exposedObject;}

1.createBeanInstance() Bean实例化

该方法的最终目的是把对象给创建出来,但创建完成的对象只是个初始对象,还未进行属性注入,那么创建的方式分为如下4种:

  1. obtainFromSupplier() :通过 Supplier 实例化
  2. instantiateUsingFactoryMethod():通过工厂方法实例化
  3. autowireConstructor():用合适的构造函数实例化
  4. instantiateBean():用无参构造函数实例化

这个方法会依次进行判断,当然其中最麻烦肯定是有参构造的判断,需要判断各种参数,而且判断通过以后,需要把这个构造方法缓存一下

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.// <1> 解析class属性Class<?> beanClass = resolveBeanClass(mbd, beanName);// 判断类是否为public类,代表是否可实例化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());}// <2> 通过Supplier回调,初始化Bean【也是注入Bean的一种方式,很少使用】Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}// <3> 通过 factory-method 初始化Beanif (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...// <4> 缓存机制, (一般单例用不到,多例的适合才用到缓存)boolean resolved = false; // 是否解析过,也就是之前是否已经创建过对象了boolean autowireNecessary = false; // 是否需要自动装配// 如果有参数,那么创建的对象肯定不一样,就不能用缓存了if (args == null) {synchronized (mbd.constructorArgumentLock) {// resolvedConstructorOrFactoryMethod 缓存已经解析的构造函数或是工厂方法,// 其类型为Executable 是Method、Constructor类型的父类if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved; // 构造函数参数标记为已解析}}}// <5> 使用缓存if (resolved) {if (autowireNecessary) {// 有参构造函数自动注入return autowireConstructor(beanName, mbd, null, null);}else {// 使用默认的无参构造return instantiateBean(beanName, mbd);}}// <6> 从bean后置处理器中为自动装配寻找构造方法// 一般就是二种情况: 1) 只有一个有参构造方法  2) 有且仅有@Autowired注解构造Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);// 以下情况符合其一即可进入// 1、存在可选构造方法 // 2、自动装配模型为构造函数自动装配// 3、给BeanDefinition中设置了构造参数值// 4、有参与构造函数参数列表的参数if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {// 通过有参构造方法初始化beanreturn autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?// <7> 找出最合适的默认构造方法ctors = mbd.getPreferredConstructors();if (ctors != null) {// 有参构造函数自动注入return autowireConstructor(beanName, mbd, ctors, null);}// <8> 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);
}

<1> obtainFromSupplier()

该方式比较偏门,几乎不使用

这里首先介绍一下Supplier这个接口,它里面只有一个get()方法,它和@ComponentFactoryBean这些一样,都是注入Bean的方式,只不过这种方式很少使用,在之前的文章中介绍过该接口

那么回到这个方法中,主体就是调用get()这个方法获取实例

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {Object instance;String outerBean = this.currentlyCreatedBean.get();this.currentlyCreatedBean.set(beanName);try {// 通过调用get()方法, 这里函数式接口,实际上会调用传入的方法初始化Beaninstance = instanceSupplier.get();}finally {if (outerBean != null) {this.currentlyCreatedBean.set(outerBean);}else {this.currentlyCreatedBean.remove();}}if (instance == null) {instance = new NullBean();}BeanWrapper bw = new BeanWrapperImpl(instance);initBeanWrapper(bw);return bw;
}

<2> instantiateUsingFactoryMethod()

返回值会创建一个解析类ConstructorResolver, 然后调用instantiateUsingFactoryMethod() 这个方法,这个方法里面的代码太长了,增加了非常多的判断,这里不做具体解读,概述一下实现的功能:

  1. 当只配置了factory-method,则该方法必须为静态方法,可以直接调用静态方法创建对象,否则抛出异常,这就是静态工厂模式
  2. 当配置了factory-method + factory-bean,则代表该方法为普通方法,则,这就是实例工厂模式
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

<3> 有参构造创建

这里会调用autowireConstructor(),有参构造函数自动注入,源码很长就不解读了,有以下原因:

  1. 很多源码的构造方法都定义很多逻辑,但是自己开发,还是更多的使用无参构造方法
  2. 有参构造可以有多个,而且参数的类型、顺序不同, 这就导致有很多的可能性,尤其那个参数类型,例如:我定义有参构造的参数类型为Object,这就需要一个类型匹配规则
  3. 而且这里还会处理@Autowired注解,构造方法上面加该注解,代表参数可以从Bean容器中依赖注入,这从方法名autowireConstructor()带了autowire这个词可以看到

就相当于从各种各样的构造方法中寻找最适合的那个

<4> 无参构造初始化

这里会调用instantiateBean(),具体源码就不解读了,肯定是借助Java反射机制,简单介绍一下步骤:

  1. 获取到Class类

  2. 通过Class获取到构造方法clazz.getDeclaredConstructor()

  3. 有了构造方法,接下来就反射创建一个对象即可ctor.newInstance()

2.扩展机制修改BeanDefinition

提供的扩展机制,允许通过后置处理器的方式,修改RootBeanDefinition

// Allow post-processors to modify the merged bean definition.
// 允许后处理器修改合并的 bean 定义。
synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}
}

遍历执行后置处理器

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);}
}

3.是否提前暴露bean

是否提前暴露该bean是为了解决单例情况下的循环依赖

// 判断条件 = 单例bean && 配置允许提前暴暴露 && 当前bean正在创建中(如果都没有开始创建往缓存加个球)
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));
}

addSingletonFactory()

如果允许提前暴露,那么就会加入将该Bean以ObjectFactory的形式加入到三级缓存,主要为了适配AOP的循环依赖,后续会有单独篇幅介绍循环依赖。

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {// 单例缓存中不存在该beanif (!this.singletonObjects.containsKey(beanName)) {// 存入三级缓存,对象是ObjectFactory类型this.singletonFactories.put(beanName, singletonFactory);// 二级缓存清空一下this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}
}

getEarlyBeanReference()

存入到三级缓存的是ObjectFactory,是个Lambda的形式,当调用getObject()实际上会调用getEarlyBeanReference(),Spring框架最重要的AOP就是在这里这里创建的代理

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);}}return exposedObject;
}

【举例】

上面用到了bp.getEarlyBeanReference(exposedObject, beanName),如果使用了AOP,这里面是递归到了AbstractAutoProxyCreator类,就是处理AOP的类

// AbstractAutoProxyCreator#getEarlyBeanReference()
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {Object cacheKey = getCacheKey(bean.getClass(), beanName);this.earlyProxyReferences.put(cacheKey, bean);return wrapIfNecessary(bean, beanName, cacheKey);
}

4.populateBean() 属性填充

  1. 获取bean中哪些属性需要注入,注入的模式
  2. 定义MutablePropertyValues,存储需要注入的属性
  3. 根据名称注入,将需要注入的bean存储到MutablePropertyValues中,注意此时只是获取了,但是还没有绑定关系
  4. 根据类型注入,同样保存到MutablePropertyValues中,没有绑定到属性上
  5. 依赖检查
  6. bean绑定到属性上
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// 一般正常注入都是有值的if (bw == null) {// 如果BeanWrapper为空,但是有属性值,就跑异常if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");}else {// 没有可填充的属性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.// 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值// 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}// 获取需要注入的属性值PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 获取装配模式int resolvedAutowireMode = mbd.getResolvedAutowireMode();if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {// 1)把需要注入的属性先拷贝过来  2)经过下面的方法,获取到需要注入的bean,也会存到这里面来// 简单点说,就是这里面存储了哪些属性需要注入,然后下面获取到也存到这里面来, 但此时还没有进行引用关系的绑定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;}// 容器是否注册了InstantiationAwareBeanPostProcessorboolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();// 是否进行依赖检查boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = bp.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);}// 上面获取的属性是以PropertyValues形式存在的, 需要注入到bean中if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}
}

autowireByName() 根据名称自动注入

通过名称,将需要注入的属性添加到MutablePropertyValues

protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 获取到需要依赖注入的属性// 获取到可写的(即set方法存在) && 非简单属性(包装类+Number+Date) 的属性名String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {// 判断缓存中是否有当前beanif (containsBean(propertyName)) {// 递归初始化相关的beanObject bean = getBean(propertyName);// 把需要注入的bean存进去pvs.add(propertyName, bean);// 注册依赖,将依赖关系保存到dependentBeanMapdependentBeanMap 中,key是 bean,value是 转化后的 propertyNameregisterDependentBean(propertyName, beanName);if (logger.isTraceEnabled()) {logger.trace("Added autowiring by name from bean name '" + beanName +"' via property '" + propertyName + "' to bean named '" + propertyName + "'");}}else {if (logger.isTraceEnabled()) {logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +"' by name: no matching bean found");}}}
}

autowireByType() 根据类型自动注入

通过类型,将需要注入的属性添加到MutablePropertyValues

protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 获取自定义的类型转换器TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}Set<String> autowiredBeanNames = new LinkedHashSet<>(4);// 过滤出满足装配条件的Bean属性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {try {// 获取属性描述符PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);// Don't try autowiring by type for type Object: never makes sense,// even if it technically is an unsatisfied, non-simple property.// 这里不解析Object的官方注释 :不要尝试按类型为Object类型自动装配:即使从技术上讲是不满意的,非简单的属性,也从没有意义。if (Object.class != pd.getPropertyType()) {// 获取指定属性的 set 方法MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);// Do not allow eager init for type matching in case of a prioritized post-processor.boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);// 解析指定beanName 的属性所匹配的值,并把解析到的属性名存储在 autowiredBeanNames  中// 当属性存在多个封装bean时,如 @Autowired List<Bean> beans,会找到所有的匹配Bean 类型的bean并将其注入。// 这里的返回值是真正的需要注入的属性, autowiredBeanNames 是需要注入的属性(可能是集合)的namesObject autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument != null) {// 添加到待注入的bean列表中pvs.add(propertyName, autowiredArgument);}// 注册依赖for (String autowiredBeanName : autowiredBeanNames) {// 注册依赖关系。操作 dependentBeanMap 和  dependenciesForBeanMap 集合registerDependentBean(autowiredBeanName, beanName);if (logger.isTraceEnabled()) {logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +propertyName + "' to bean named '" + autowiredBeanName + "'");}}autowiredBeanNames.clear();}}catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);}}
}

applyPropertyValues() 属性注入

上面已经通过名称/类型获取到了属性,并且添加到了PropertyValues中,但是此时还没有添加到bean中,下面的方法就是负责这个

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {// 如果属性列表为null,直接返回if (pvs.isEmpty()) {return;}if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());}MutablePropertyValues mpvs = null;List<PropertyValue> original;// 如果pvs 是 MutablePropertyValues 类型的封装if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;// 判断 mpvs 中的值类型已经转换完毕,则可以直接设置到BeanWrapper 中if (mpvs.isConverted()) {try {bw.setPropertyValues(mpvs);return;}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);}}original = mpvs.getPropertyValueList();}else {original = Arrays.asList(pvs.getPropertyValues());}// 获取自定义转换类型,如果为null ,使用默认的bw, BeanWrapper 类继承了 TypeConverter TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);// 这里是创建一个深度拷贝的list,解决值引用相关的问题List<PropertyValue> deepCopy = new ArrayList<>(original.size());boolean resolveNecessary = false;for (PropertyValue pv : original) {// 如果已经转换之后直接保存if (pv.isConverted()) {deepCopy.add(pv);}else {// 进行类型转换String propertyName = pv.getName();Object originalValue = pv.getValue();Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);Object convertedValue = resolvedValue;// 检查给定的属性是否可写, 或者检查属性是否是索引或嵌套的属性,比如a.b , 或者 [a,b]boolean convertible = bw.isWritableProperty(propertyName) &&!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);// 进行类型转换if (convertible) {convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);}// 将转换转换的值保存在pv 里面,同时加到深度拷贝list里面if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);}deepCopy.add(pv);}else if (convertible && originalValue instanceof TypedStringValue &&!((TypedStringValue) originalValue).isDynamic() &&!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);deepCopy.add(pv);}else {resolveNecessary = true;deepCopy.add(new PropertyValue(pv, convertedValue));}}}// 设置为已经转换过,避免后续的转换if (mpvs != null && !resolveNecessary) {mpvs.setConverted();}// 这里就是最后将转换后的值,进行赋值填充try {bw.setPropertyValues(new MutablePropertyValues(deepCopy));}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);}
}

5.initializeBean() 初始化

  1. 执行3个处理器,BeanNameAwareBeanClassLoaderAwareBeanFactoryAware
  2. 执行BeanPostProcessor后置处理器的postProcessBeforeInitialization()
  3. 执行InitializingBean接口的afterPropertiesSet()
  4. 执行init-method初始化方法
  5. 执行BeanPostProcessor后置处理器的postProcessAfterInitialization()
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 {// 调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAwareinvokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// 应用前置处理器wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 激活用户自定义的init方法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;
}

invokeAwareMethods()

如果该bean实现了对应的Aware接口,那么会负责实现,下面的代码就很简答了,分别负责处理BeanNameAwareBeanClassLoaderAwareBeanFactoryAware

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);}}
}

处理器的应用

BeanPostProcess是Spring开放式架构中一个必不可少的亮点,给用户充足的权限去更改或者扩展Spring。这里就是调用其注册的处理器,对bean进行处理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;
}
@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;
}

激活自定义的init方法

客户定制的初始化方法除了我们使用的配置init-method外,还有使自定义的bean实现InitializingBean接口,并在afterPropertiesSet()初始化业务逻辑

这2个都会在该方法中进行初始化,执行顺序为:

  1. afterPropertiesSet()
  2. init-method
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {// 1.检查该bean是否实现了InitializingBean接口boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("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) bean).afterPropertiesSet();}}// 2.执行init-method方法if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {// 看到这里的方法名带个invoke就猜到会通过反射调用invokeCustomInitMethod(beanName, bean, mbd);}}
}

6.循环依赖检查

在Spring中解决循环依赖只对单例有效,而对于多例的bean,Spring没有好的解决办法,唯一要做的就是抛出异常

// 允许提前暴露Bean
if (earlySingletonExposure) {// 尝试从缓存获取,如果存在循环依赖,那么缓存中会存在Object earlySingletonReference = getSingleton(beanName, false);// 只要检测到循环依赖的情况才有值if (earlySingletonReference != null) {// 如果exposedObject没有在上面的初始化中被改变,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.");}}}
}

7.销毁方法处理

如果配置了destroy-method,这里需要注册以便于在销毁时候调用

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {// Register a DisposableBean implementation that performs all destruction// work for the given bean: DestructionAwareBeanPostProcessors,// DisposableBean interface, custom destroy method.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));}else {// A bean with a custom scope...Scope scope = this.scopes.get(mbd.getScope());if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");}scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));}}
}