1. 前言:
在Spring的AbstractAutowireCapableBeanFactory
中,方法繁多,但它们的功能可以大致归类为以下几个主要类别:
1. Bean工厂配置方法
这一类方法用于配置BeanFactory
的行为。它们允许设置实例化策略、是否允许循环引用、参数名称发现器等。主要包括:
setInstantiationStrategy()
setParameterNameDiscoverer()
setAllowCircularReferences()
setAllowRawInjectionDespiteWrapping()
ignoreDependencyType()
ignoreDependencyInterface()
copyConfigurationFrom()
2. Bean创建和实例化方法
这些方法负责Bean的创建、实例化过程。它们处理从Bean定义到Bean实例化的整个过程,包括依赖注入、生命周期回调等。主要包括:
createBean()
autowireBean()
configureBean()
createBeanInstance()
doCreateBean()
3. 依赖处理方法
这一类方法用于处理Bean之间的依赖,包括自动装配和依赖查找。它们确保了Bean的依赖能被正确解析和注入。主要包括:
resolveDependency()
autowireBeanProperties()
populateBean()
4. Bean初始化和销毁方法
这些方法涉及到Bean生命周期的管理,包括初始化前后的处理、自定义初始化方法的调用,以及销毁方法的调用。主要包括:
initializeBean()
invokeInitMethods()
destroyBean()
5. 类型转换和Bean后处理器调用
此类别方法处理类型转换和Bean后处理器的调用,这对于Spring的数据绑定和扩展非常重要。主要包括:
applyBeanPostProcessorsBeforeInitialization()
applyBeanPostProcessorsAfterInitialization()
6. 工具和辅助方法
这一类方法提供了各种工具和辅助功能,如日志记录、异常处理、解析Bean名称、处理工厂Bean等。主要包括:
getBeanPostProcessors()
resolveBeanByName()
applyMergedBeanDefinitionPostProcessors()
每个类别的方法协同工作,共同支撑了Spring框架的IoC容器功能,实现了依赖注入、Bean的生命周期管理等核心特性。
2. 流程分析:
2.1 大致流程
sheel
getBean(name)
|
V
doGetBean()
|
V
createBean()
|
V
resolveBeforeInstantiation(beanName, mbd) -----> Bean存在? -----> Yes -----> 结束
| |
No |
| |
V |
doCreateBean() ------------------------------------------------------
|
|---> createBeanInstance() // 实例化Bean
| |
| V
| populateBean() // 依赖注入
| |
| V
| initializeBean() // 初始化Bean
| |
| |---> applyBeanPostProcessorsBeforeInitialization()
| | |
| | V
| | invokeInitMethods() // 调用自定义初始化方法
| | |
| | V
| | applyBeanPostProcessorsAfterInitialization()
| |
| V
| registerDisposableBeanIfNecessary() // 注册销毁回调
|
V
结束
2.2 流程方法说明
2.2.1. 创建前检查createBean
- 这里主要是一些bean的准备工作,解析类的信息,日志之类的东西
- 值得注意是 bean 的前置处理,如果返回了bean的代理对象(aop),则会跳过下面的正常创建流程。
java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
}
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
如果没有创建代理对象则跳转到
doCreateBean()
创建对象
2.2.2. 检查缓存
factoryBeanInstanceCache是一个专门用来缓存FactoryBean创建的bean实例的缓存,而不是通常提到的处理循环依赖的一级、二级或三级缓存。
java
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
spring bean默认是单例模式,如果是单例模式的话,清除工厂缓存中的早期引用。
2.2.3. 实例化Bean
通过
createBeanInstance(beanName, mbd, args);
方法创建实例
java
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
java
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, mbd);
} else if (mbd.getFactoryMethodName() != null) {
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);
}
}
}
}
}
- 通过Supplier创建Bean实例
- 如果Bean定义指定了一个
Supplier
来提供Bean的实例,则直接调用Supplier.get()
方法来创建Bean实例。这是一个Java 8引入的功能,允许以编程方式控制Bean的实例化过程。
- 通过工厂方法创建Bean实例
- 如果Bean定义指定了工厂方法(
factoryMethodName
不为null),则使用该工厂方法来创建Bean实例。这涉及到查找并调用相应的静态或实例级工厂方法。
- 自动装配构造器创建Bean实例
- 如果Bean定义没有指定工厂方法,方法会尝试通过构造器自动装配来创建Bean实例。这个过程可能包括:
- 检查是否已经解析了构造器或工厂方法及其参数(用于快速实例化)。
- 如果没有解析过,或者传入了显式的构造器参数
args
,则尝试通过BeanPostProcessors推断合适的构造器(determineConstructorsFromBeanPostProcessors
),或者使用Bean定义中指定的"首选"构造器。
- 直接实例化Bean
- 如果没有指定工厂方法,也没有找到适用的构造器,那么会尝试直接使用无参构造器来实例化Bean(如果可能的话)。
- 返回BeanWrapper包装的实例
2.2.3. 设置Bean的类型
java
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
如果存储bean 类型的元数据
2.2.4. Bean定义的后处理
java
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.markAsPostProcessed();
}
}
在Bean实例化后、属性填充前,执行Bean定义的后处理器。
2.2.5. 处理循环依赖
java
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);
});
}
在单例模式,允许循环依赖,且bean可能正在创建(说明被循环依赖),如果存在互相引用,添加一个能够生成Bean早期引用的工厂对象到单例对象的缓存中。
2.2.6. 属性填充且初始化
java
try {
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException bce) {
if (beanName.equals(bce.getBeanName())) {
throw bce;
}
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, var18.getMessage(), var18);
}
- 初始化方法
java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
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, var6.getMessage(), var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
- 调用Aware接口方法
java
this.invokeAwareMethods(beanName, bean);
- 这一步主要是为了调用实现了
Aware
接口的bean的相应方法,让bean能够访问Spring容器的某些部分,比如BeanNameAware
,BeanFactoryAware
,ApplicationContextAware
等。这样bean就可以获取到它的名称、所属的BeanFactory或者ApplicationContext。
- 应用前置处理器
java
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean,beanName);
- 在bean的初始化方法被调用之前,这一步会遍历并调用已注册的所有
BeanPostProcessor
的postProcessBeforeInitialization
方法。这给了开发者一个机会在bean属性设置完成后、自定义初始化之前对bean实例进行额外的处理,比如检查或修改bean的属性。
3 调用初始化方法
java
this.invokeInitMethods(beanName, wrappedBean, mbd);
- 这一步负责调用bean的初始化方法。如果bean实现了
InitializingBean
接口,将会调用其afterPropertiesSet
方法。此外,如果在bean定义中通过init-method
属性指定了自定义的初始化方法,也会在这里被调用。
- 应用后置处理器
java
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
- 在bean的初始化方法被调用之后,这一步会遍历并调用已注册的所有
BeanPostProcessor
的postProcessAfterInitialization
方法。这为开发者提供了另一个机会在bean完全初始化之后对其进行额外的处理,比如创建代理来增强bean的功能。
2.2.7. 处理早期的bean引用实例
这一步的核心是,循环依赖早期暴露的bean和现在完全初始化后的一致,就ok,如果不一致,就都别运行了。
java
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.");
}
}
}
}
2.2.8. 返回经过处理的bean
java
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}