Bean的加载 createBean()
Posted 为人师表好少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bean的加载 createBean()相关的知识,希望对你有一定的参考价值。
前言
在上一章的doGetBean()
中,介绍了创建Bean前的各种处理,那么具体实例化Bean的功能则调用createBean()
,该方法由AbstractAutowireCapableBeanFactory
类重写,下面来解读一下源码:
一、createBean()
该方法大体步骤如下:
- 根据bean定义信息和bean名称解析得到bean的Class类型
- 验证并准备为此 bean 定义的方法覆盖,对应bean中的
lookup-method
+replaced-method
2个属性,【不好维护,平常少用,特殊情况使用】 - 给
InstantiationAwareBeanPostProcessor
后置处理器一个机会,返回代理对象用来替换目标bean实例; - 执行真正创建bean的方法 ==>
doCreateBean()
; - 返回创建好的bean实例;
@Override
protected 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属性,存储的是字符串
// 这里这么多判断就是为了确定已经解析了Bean
if (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
整体方法的逻辑很简单
- 如果通过该
BeanDefinition
创建过实例,那么其中肯定会有存储,例如多例的Bean - 如果是第一次创建,那么会通过
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()
执行步骤
-
单例,则首先尝试从【未完成的FactoryBean实例缓存】获取
-
【Bean实例化】。可以通过4种方式来实例化
-
扩展机制:
MergedBeanDefinitionPostProcessor
后置处理器的应用,允许它修改RootBeanDefinition
-
是否允许提前暴露bean对象,用于解决循环依赖问题,暴露方式为加入三级缓存
-
【Bean属性填充】
-
【Bean初始化】
-
如果允许早期暴露,需要进行循环依赖检查
-
注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理;
-
完成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对象和Class
Object 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的属性,则会递归初始化依赖的bean
populateBean(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种:
obtainFromSupplier()
:通过Supplier
实例化instantiateUsingFactoryMethod()
:通过工厂方法实例化autowireConstructor()
:用合适的构造函数实例化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 初始化Bean
if (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))
// 通过有参构造方法初始化bean
return 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()
方法,它和@Component
、FactoryBean
这些一样,都是注入Bean的方式,只不过这种方式很少使用,在之前的文章中介绍过该接口
那么回到这个方法中,主体就是调用get()
这个方法获取实例
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName)
Object instance;
String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(<spring源码分析IOC容器初始化
- 前言:在上文bean加载过程中还要一个非常重要的方法没有分析createBean,该方法非常重要,因此特意提出来单独分析。
createBean方法定义在AbstractBeanFactory中:

该方法根据给定的beanName、BeanDefinition和args实例化一个bean对象。所有bean实例的创建都会委托给该方法实现。
AbstractAutowireCapableBeanFactory#createBean
createBean的默认实现在AbstractAutowireCapableBeanFactory类中,代码如下:
1 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
2 throws BeanCreationException {
3 if (logger.isDebugEnabled()) {
4 logger.debug("Creating instance of bean ‘" + beanName + "‘");
5 }
6 RootBeanDefinition mbdToUse = mbd;
7
8 // Make sure bean class is actually resolved at this point, and
9 // clone the bean definition in case of a dynamically resolved Class
10 // which cannot be stored in the shared merged bean definition.
11 // 确保此时的bean已经被解析了
12 // 如果获取的class属性不为null,则克隆该BeanDefinition,主要是因为动态解析的class无法保存到共享的BeanDefinition
13 Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
14 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
15 mbdToUse = new RootBeanDefinition(mbd);
16 mbdToUse.setBeanClass(resolvedClass);
17 }
18
19 // Prepare method overrides.
20 try {
21 // 验证和准备覆盖方法
22 mbdToUse.prepareMethodOverrides();
23 } catch (BeanDefinitionValidationException ex) {
24 throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
25 beanName, "Validation of method overrides failed", ex);
26 }
27
28 try {
29 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
30 // 实例化的前置处理
31 // 给BeanPostProcessor一个机会用来返回一个代理类而不是真正的实例类
32 // AOP的功能就是基于这个地方
33 Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
34 if (bean != null) {
35 return bean;
36 }
37 } catch (Throwable ex) {
38 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
39 "BeanPostProcessor before instantiation of bean failed", ex);
40 }
41
42 try {
43 // 创建Bean对象
44 Object beanInstance = doCreateBean(beanName, mbdToUse, args);
45 if (logger.isDebugEnabled()) {
46 logger.debug("Finished creating instance of bean ‘" + beanName + "‘");
47 }
48 return beanInstance;
49 } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
50 // A previously detected exception with proper bean creation context already,
51 // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
52 throw ex;
53 } catch (Throwable ex) {
54 throw new BeanCreationException(
55 mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
56 }
57 }
分析:
- 通过resolveBeanClass解析BeanDefinition的class属性。
- 处理override属性。
- 通过resolveBeforeInstantiation进行实例化的前置处理。
- 最后通过doCreateBean创建bean对象。
AbstractBeanFactory#resolveBeanClass
1 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
2 throws CannotLoadBeanClassException {
3
4 try {
5 if (mbd.hasBeanClass()) {
6 return mbd.getBeanClass();
7 }
8 if (System.getSecurityManager() != null) {
9 return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
10 doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
11 } else {
12 return doResolveBeanClass(mbd, typesToMatch);
13 }
14 // ..... 省略异常处理
15 }
分析:
该方法主要是解析BeanDefinition的class类,如果解析的class类不为空,则将其设置到mbdToUse中,因为动态解析的class无法保存到共享的BeanDefinition中。
AbstractBeanFactory#prepareMethodOverrides
1 public void prepareMethodOverrides() throws BeanDefinitionValidationException {
2 // Check that lookup methods exists.
3 // 如果方法可以覆盖
4 if (hasMethodOverrides()) {
5 // 得到覆盖方法
6 Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
7 // 同步
8 synchronized (overrides) {
9 // 循环调用 prepareMethodOverride进行覆盖准备
10 for (MethodOverride mo : overrides) {
11 prepareMethodOverride(mo);
12 }
13 }
14 }
15 }
分析:
bean标签中的lookup-method和replace-method属性就是放在BeanDefinition的methodOverrides属性中(关于这两个属性的分析后续再来分析),这里就是对methodOverrides属性进行处理,动态为当前bean生产代理并使用对应的拦截器为bean做增强处理。
上述处理逻辑就是循环获取MethodOverride属性,然后调用prepareMethodOverride进行处理。
1 // AbstractBeanDefinition
2 protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
3 int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
4 if (count == 0) {
5 throw new BeanDefinitionValidationException(
6 "Invalid method override: no method with name ‘" + mo.getMethodName() +
7 "‘ on class [" + getBeanClassName() + "]");
8 } else if (count == 1) {
9 // Mark override as not overloaded, to avoid the overhead of arg type checking.
10 mo.setOverloaded(false);
11 }
12 }
分析:
根据方法名,从class中获取该方法名的个数:
- 如果方法名个数为0,则抛出BeanDefinitionValidationException异常,原因其实很简单:通过方法名去查找,而又没有找到,则说明有问题的,抛出异常。
- 如果方法名个数为1,则设置该方法未被重载(overloaded属性模式为true)。如果一个类存在多个重载方法,在方法调用的时候还需根据参数类型来判断到底重载的是哪个方法,这里通过count=1,来表示该方法未被重载,在调用的时候可以直接找方法而不需要进行方法参数的校验,相当于一个小小的优化,提升后面调用函数的速度。
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
1 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
2 Object bean = null;
3 // 如果bean不是应用系统的,有BeanPostProcessor
4 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
5 // Make sure bean class is actually resolved at this point.
6 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
7 Class<?> targetType = determineTargetType(beanName, mbd);
8 if (targetType != null) {
9 // 前置处理
10 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
11 if (bean != null) {
12 // 后置处理
13 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
14 }
15 }
16 }
17 mbd.beforeInstantiationResolved = (bean != null);
18 }
19 return bean;
20 }
分析:
通过applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization对bean实例化前进行前置与后置处理。如果返回了代理对象,则直接返回结果,Spring后续实现AOP就是基于这个地方进行的判断。
前置处理与后置处理后续再具体进行分析。
AbstractAutowireCapableBeanFactory#doCreateBean
1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
2 throws BeanCreationException {
3
4 // Instantiate the bean.
5 // BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象、获取被包装bean的属性描述器
6 BeanWrapper instanceWrapper = null;
7 // 如果是单例模型,则从未完成的FactoryBean缓存中删除
8 if (mbd.isSingleton()) {
9 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
10 }
11 // 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
12 if (instanceWrapper == null) {
13 instanceWrapper = createBeanInstance(beanName, mbd, args);
14 }
15 // 包装的对象实例
16 final Object bean = instanceWrapper.getWrappedInstance();
17 // 包装的实例对象的类型
18 Class<?> beanType = instanceWrapper.getWrappedClass();
19 if (beanType != NullBean.class) {
20 mbd.resolvedTargetType = beanType;
21 }
22
23 // Allow post-processors to modify the merged bean definition.
24 // 先做同步,然后判断是否有后置处理
25 synchronized (mbd.postProcessingLock) {
26 if (!mbd.postProcessed) {
27 try {
28 // 后置处理修改BeanDefinition
29 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
30 } catch (Throwable ex) {
31 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
32 "Post-processing of merged bean definition failed", ex);
33 }
34 mbd.postProcessed = true;
35 }
36 }
37
38 // Eagerly cache singletons to be able to resolve circular references
39 // even when triggered by lifecycle interfaces like BeanFactoryAware.
40 // 解决单例模式的循环依赖 // 单例模式 运行循环依赖
41 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
42 isSingletonCurrentlyInCreation(beanName));// 当前单例bean是否正在被创建
43 if (earlySingletonExposure) {
44 if (logger.isDebugEnabled()) {
45 logger.debug("Eagerly caching bean ‘" + beanName +
46 "‘ to allow for resolving potential circular references");
47 }
48 // 提前将创建的bean实例加入到singletonFactories中
49 // 为了后期避免循环依赖
50 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
51 }
52
53 // Initialize the bean instance.
54 // 开始初始化bean实例对象
55 Object exposedObject = bean;
56 try {
57 // 对bean进行填充,主要是进行属性注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖bean
58 populateBean(beanName, mbd, instanceWrapper);
59 // 进行bean初始化
60 exposedObject = initializeBean(beanName, exposedObject, mbd);
61 } catch (Throwable ex) {
62 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
63 throw (BeanCreationException) ex;
64 } else {
65 throw new BeanCreationException(
66 mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
67 }
68 }
69
70 // 循环依赖处理
71 if (earlySingletonExposure) {
72 // 获取earlySingletonReference
73 Object earlySingletonReference = getSingleton(beanName, false);
74 // 只有在循环依赖的情况下,earlySingletonReference才不会为null
75 if (earlySingletonReference != null) {
76 // 如果exposedObject没有在初始化方法中改变,也就是没有被增强
77 if (exposedObject == bean) {
78 exposedObject = earlySingletonReference;
79 } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 处理依赖
80 String[] dependentBeans = getDependentBeans(beanName);
81 Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
82 for (String dependentBean : dependentBeans) {
83 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
84 actualDependentBeans.add(dependentBean);
85 }
86 }
87 if (!actualDependentBeans.isEmpty()) {
88 throw new BeanCurrentlyInCreationException(beanName,
89 "Bean with name ‘" + beanName + "‘ has been injected into other beans [" +
90 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
91 "] in its raw version as part of a circular reference, but has eventually been " +
92 "wrapped. This means that said other beans do not use the final version of the " +
93 "bean. This is often the result of over-eager type matching - consider using " +
94 "‘getBeanNamesOfType‘ with the ‘allowEagerInit‘ flag turned off, for example.");
95 }
96 }
97 }
98 }
99
100 // Register bean as disposable.
101 try {
102 // 注册bean
103 registerDisposableBeanIfNecessary(beanName, bean, mbd);
104 } catch (BeanDefinitionValidationException ex) {
105 throw new BeanCreationException(
106 mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
107 }
108
109 return exposedObject;
110 }
分析:
如果没有代理对象,则会进行bean对象的创建。
- 如果BeanDefinition为单例模式,首先从FactoryBean缓存中删除该beanName的缓存。
- 调用createBeanInstance方法创建一个BeanWrapper对象。
- 调用applyMergedBeanDefinitionPostProcessors对BeanDefinition进行后置处理
- 进行单例模式的循环依赖处理。
- 调用populateBean进行bean属性填充。
- 调用initializeBean进行bean初始化。
- 进行依赖检查。
- 最后注册bean。
上述列出了创建bean对象的主要步骤,过程还是比较复杂的,下面一一进行分析。主要关注点createBeanInstance、populateBean、initializeBean三个函数。
AbstractAutowireCapableBeanFactory#createBeanInstance
1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
2 // Make sure bean class is actually resolved at this point.
3 // 解析bean,将bean类名解析为class引用
4 Class<?> beanClass = resolveBeanClass(mbd, beanName);
5
6 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
7 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
8 "Bean class isn‘t public, and non-public access not allowed: " + beanClass.getName());
9 }
10
11 // 如果存在supplier回调,则使用给定的回调方法初始化策略
12 Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
13 if (instanceSupplier != null) {
14 return obtainFromSupplier(instanceSupplier, beanName);
15 }
16
17 // 使用FactoryBean的factor-method来创建bean,支持静态工厂和实例工厂
18 if (mbd.getFactoryMethodName() != null) {
19 return instantiateUsingFactoryMethod(beanName, mbd, args);
20 }
21
22 // Shortcut when re-creating the same bean...
23 boolean resolved = false;
24 boolean autowireNecessary = false;
25 if (args == null) {
26 // 做同步
27 synchronized (mbd.constructorArgumentLock) {
28 // 如果已缓存的解析构造函数或者工厂方法不为null,则可以利用构造函数解析
29 // 因为需要根据参数确认到底使用哪个构造函数,该过程比较消耗性能,所以采用缓存机制
30 if (mbd.resolvedConstructorOrFactoryMethod != null) {
31 resolved = true;
32 autowireNecessary = mbd.constructorArgumentsResolved;
33 }
34 }
35 }
36 // 已经解析好了,直接注入即可
37 if (resolved) {
38 // autowire自动注入,调用构造函数自动注入
39 if (autowireNecessary) {
40 return autowireConstructor(beanName, mbd, null, null);
41 } else {
42 // 使用默认构造函数构造
43 return instantiateBean(beanName, mbd);
44 }
45 }
46
47 // Need to determine the constructor...
48 // 确定解析的构造函数
49 // 主要是检查已经注册的SmartInstantiationAwareBeanPostProcessor
50 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
51 // 确定构造方法进行bean创建
52 if (ctors != null ||
53 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
54 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
55 return autowireConstructor(beanName, mbd, ctors, args);
56 }
57
58 // 有参数,又没有获取到构造方法,则只能调用无参构造方法来创建实例
59 // 这是一个兜底的方法
60 // No special handling: simply use no-arg constructor.
61 return instantiateBean(beanName, mbd);
62 }
分析:
bean的实例化一个比较复杂的过程。
- 如果设置Supplier回调,则调用obtainFromSupplier方法进行初始化。
- 如果存在工厂方法,则使用工厂方法进行初始化。
- 先判断缓存中是否存在构造函数,如果存在,则根据是否使用自动注入,还是默认的构造函数进行bean对象的初始化。
- 如果缓存中不存在,则需先判断到底使用哪个构造函数来完成解析工作。
- 如果上述条件还是不满足,则使用无参构造方法来创建实例。
#1.如果设置Supplier回调,则使用obtainFromSupplier方法进行初始化。
首先了解下Supplier接口(java.util.function):

- Supplier接口仅有一个功能性的get()方法,该方法会返回一个<T>类型的对象,有点类似工厂方法。
- 如果我们在创建BeanDefinition的时候设置了Supplier参数,那么其他的构造器或者工厂方法就没有作用了。
- AbstractBeanDefinition中提供了设置Supplier的入口:

AbstractAutowireCapableBeanFactory#obtainFromSupplier
1 protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
2 // 获得原创建的Bean的对象名
3 String outerBean = this.currentlyCreatedBean.get();
4 // 设置新的Bean对象名到currentlyCreatedBean中
5 this.currentlyCreatedBean.set(beanName);
6 Object instance;
7 try {
8 // 调用Supplier的get(),返回一个Bean对象
9 instance = instanceSupplier.get();
10 } finally {
11 // 设置原创建的Bean对象名到currentlyCreatedBean中
12 if (outerBean != null) {
13 this.currentlyCreatedBean.set(outerBean);
14 } else {
15 this.currentlyCreatedBean.remove();
16 }
17 }
18 // 创建BeanWrapper对象
19 BeanWrapper bw = new BeanWrapperImpl(instance);
20 // 初始化BeanWrapper
21 initBeanWrapper(bw);
22 return bw;
23 }
分析:
- 调用Supplier#get方法,获取一个Bean实例对象。
- 根据该实例对象构建BeanWrapper对象。
- 最后初始化该对象。
如果存在工厂方法,则会调用工厂方法来完成bean的初始化工作,该方法实现比较长,并且细节复杂,由于篇幅原因放在下篇文章中解析。
总结
这里仅仅分析了doCreateBean方法中的一点点内容,如果存在Supplier回调,则会直接通过Supplier来创建Bean对象,构造函数和工厂方法则失效,下面将对分析使用工厂方法实例化Bean对象的过程。
by Shawn Chen,2019.04.23,下午。
以上是关于Bean的加载 createBean()的主要内容,如果未能解决你的问题,请参考以下文章