死磕Spring之IoC篇 - Bean 的实例化阶段
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读
Spring 版本:5.1.14.RELEASE
开始阅读这一系列文章之前,建议先查看《深入了解 Spring IoC(面试题)》这一篇文章
该系列其他文章请查看:《死磕 Spring 之 IoC 篇 - 文章导读》
Bean 的实例化阶段
当我们显示或者隐式地调用AbstractBeanFactory
的 getBean(...)
方法时,会触发 Bean 的加载,在《开启 Bean 的加载》文章中分析了整个加载过程。
对于不同作用域的 Bean,底层都会调用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法进行创建,在上一篇《Bean 的创建过程》文章中分析了整个创建过程。在创建 Bean 的过程中,需要先获取其 Class 对象,然后通过构造方法创建一个实例对象(反射机制),再进行后续的属性填充和初始化工作。整个的实例化过程非常复杂,因为需要找到最匹配的构造方法,还需要找到该方法的入参,所以会有各种处理,本文将会分析创建 Bean 过程中的实例化阶段。
回顾
先来回顾一下创建 Bean 过程中实例化阶段对应的代码:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Instantiate the bean.
/**
* <1> Bean 的实例化阶段,会将 Bean 的实例对象封装成 {@link BeanWrapperImpl} 包装对象
* BeanWrapperImpl 承担的角色:
* 1. Bean 实例的包装
* 2. {@link org.springframework.beans.PropertyAccessor} 属性编辑器
* 3. {@link org.springframework.beans.PropertyEditorRegistry} 属性编辑器注册表
* 4. {@link org.springframework.core.convert.ConversionService} 类型转换器(Spring 3+,替换了之前的 TypeConverter)
*/
BeanWrapper instanceWrapper = null;
// <1.1> 如果是单例模式,则先尝试从 `factoryBeanInstanceCache` 缓存中获取实例对象,并从缓存中移除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// <1.2> 使用合适的实例化策略来创建 Bean 的实例:工厂方法、构造函数自动注入、简单初始化
// 主要是将 BeanDefinition 转换为 BeanWrapper 对象
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// <1.3> 获取包装的实例对象 `bean`
final Object bean = instanceWrapper.getWrappedInstance();
// <1.4> 获取包装的实例对象的类型 `beanType`
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
Bean 的实例化阶段,会将 Bean 的实例对象封装成 BeanWrapperImpl 包装对象,BeanWrapperImpl 承担的角色:
- Bean 实例的包装
- PropertyAccessor 属性编辑器
- PropertyEditorRegistry 属性编辑器注册表
- ConversionService 类型转换器(Spring 3+,替换了之前的 TypeConverter)
如果是单例模式,则先尝试从 factoryBeanInstanceCache
缓存(保存 FactoryBean 类型的对象)中获取实例对象,并从缓存中移除。目前在创建 Bean 的过程中没发现往这个集合中添加缓存,暂时忽略。我们直接看到下面的一步,调用 createBeanInstance(...)
方法来创建一个实例对象,我们进去看看
开启实例对象的创建
createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法,创建一个 Bean 的实例对象,如下:
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// <1> 获取 `beanName` 对应的 Class 对象
Class<?> beanClass = resolveBeanClass(mbd, beanName);
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 实例化回调接口,则使用给定的回调方法创建一个实例对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// <3> 如果配置了 `factory-method` 工厂方法,则调用该方法来创建一个实例对象
// 通过 @Bean 标注的方法会通过这里进行创建
if (mbd.getFactoryMethodName() != null) {
// 这个过程非常复杂,你可以理解为:
// 找到最匹配的 Method 工厂方法,获取相关参数(依赖注入),然后通过调用该方法返回一个实例对象(反射机制)
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// <4> 判断这个 RootBeanDefinition 的构造方法是否已经被解析出来了
// 因为找到最匹配的构造方法比较繁琐,找到后会设置到 RootBeanDefinition 中,避免重复这个过程
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) { // 加锁
// <4.1> 构造方法已经解析出来了
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// <4.2> 这个构造方法有入参,表示需要先获取到对应的入参(构造器注入)
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// <5> 如果最匹配的构造方法已解析出来
if (resolved) {
// <5.1> 如果这个构造方法有入参
if (autowireNecessary) {
// 这个过程很复杂,你可以理解为:
// 找到最匹配的构造方法,这里会拿到已经被解析出来的这个方法,并找到入参(构造器注入),然后调用该方法返回一个实例对象(反射机制)
return autowireConstructor(beanName, mbd, null, null);
}
// <5.2> 否则,没有入参
else {
// 直接调用解析出来构造方法,返回一个实例对象(反射机制)
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// <6> 如果最匹配的构造方法还没开始解析,那么需要找到一个最匹配的构造方法,然后创建一个实例对象
/**
* <6.1> 尝试通过 SmartInstantiationAwareBeanPostProcessor 处理器的 determineCandidateConstructors 方法来找到一些合适的构造方法
* 参考 {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors}
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// <6.2> 是否满足下面其中一个条件
if (ctors != null // 上一步找到了合适的构造方法
|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR // 构造器注入
|| mbd.hasConstructorArgumentValues() // 定义了构造方法的入参
|| !ObjectUtils.isEmpty(args)) // 当前方法指定了入参
{
// 找到最匹配的构造方法,如果 `ctors` 不为空,会从这里面找一个最匹配的,
// 并找到入参(构造器注入),然后调用该方法返回一个实例对象(反射机制)
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
/**
* <7> 如果第 `6` 步还不满足,那么尝试获取优先的构造方法
* 参考 {@link org.springframework.context.support.GenericApplicationContext.ClassDerivedBeanDefinition}
*/
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
// <7.1> 如果存在优先的构造方法,则从里面找到最匹配的一个,并找到入参(构造器注入),然后调用该方法返回一个实例对象(反射机制)
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// <8> 如果上面多种情况都不满足,那只能使用兜底方法了,直接调用默认构造方法返回一个实例对象(反射机制)
return instantiateBean(beanName, mbd);
}
过程大致如下:
-
获取
beanName
对应的 Class 对象 -
如果存在 Supplier 实例化回调接口,则使用给定的回调方法创建一个实例对象,调用 obtainFromSupplier(...) 方法创建
-
如果配置了
factory-method
工厂方法,则调用该方法来创建一个实例对象,通过 @Bean 标注的方法会通过这里进行创建,调用 instantiateUsingFactoryMethod(...) 方法创建
如果上面两种情况都不是,那么就进行接下来正常创建 Bean 实例的一个过程
-
判断这个 RootBeanDefinition 的构造方法是否已经被解析出来了,因为找到最匹配的构造方法比较繁琐,找到后会设置到 RootBeanDefinition 中,避免重复这个过程
- RootBeanDefinition 的
resolvedConstructorOrFactoryMethod
是否不为空,不为空表示构造方法已经解析出来了 - 构造方法已经解析出来了,则判断它的
constructorArgumentsResolved
是否不为空,不为空表示有入参,需要先获取到对应的入参(构造器注入)
- RootBeanDefinition 的
-
如果最匹配的构造方法已解析出来
- 如果这个构造方法有入参,则找到最匹配的构造方法,这里会拿到已经被解析出来的这个方法,并找到入参(构造器注入),然后调用该方法返回一个实例对象(反射机制),调用 autowireConstructor(...) 方法创建
- 否则,没有入参,直接调用解析出来构造方法,返回一个实例对象(反射机制),调用 instantiateBean(...) 方法创建
-
如果最匹配的构造方法还没开始解析,那么需要找到一个最匹配的构造方法,然后创建一个实例对象
-
先尝试通过 SmartInstantiationAwareBeanPostProcessor 处理器找到一些合适的构造方法,保存在
ctors
中 -
是否满足下面其中一个条件:
ctors
不为空、构造器注入模式、定义了构造方法的入参、当前方法指定了入参,则找到最匹配的构造方法,如果
ctors
不为空,会从这里面找一个最匹配的,并找到入参(构造器注入),然后调用该方法返回一个实例对象(反射机制),调用 autowireConstructor(...) 方法创建
-
-
如果第
6
步还不满足,那么尝试从 RootBeanDefinition 中获取优先的构造方法- 如果存在优先的构造方法,则从里面找到最匹配的一个,并找到入参(构造器注入),然后调用该方法返回一个实例对象(反射机制),调用 autowireConstructor(...) 方法创建
-
如果上面多种情况都不满足,那只能使用兜底方法了,直接调用默认构造方法返回一个实例对象(反射机制),调用 instantiateBean(...) 方法创建
整个的实例化过程非常的复杂,主要分为以下几种情况:
- 指定了 Supplier 实例化回调接口,则回调该接口,返回一个实例对象
- 配置了
factory-method
工厂方法创建当前 Bean,则找到这个方法,然后创建一个实例对象(@Bean 注解底层原理也是这种方式) - 找到一个最匹配的构造方法,返回一个实例对象,这个构造方法会设置到这个 RootBeanDefinition 中,避免再次解析,提高性能
- 兜底方法,使用默认构造方法返回一个实例对象
这四种情况,其实就分别对应上面四个加粗的方法,接下来依次分析这四个方法
obtainFromSupplier 方法
obtainFromSupplier(Supplier<?> instanceSupplier, String beanName)
方法,通过 Supplier 回调接口获取一个实例对象,方法如下:
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
// 获得原当前线程正在创建的 Bean 的名称
String outerBean = this.currentlyCreatedBean.get();
// 设置当前线程正在创建的 Bean 的名称
this.currentlyCreatedBean.set(beanName);
try {
// <1> 调用 Supplier 的 get(),返回一个实例对象
instance = instanceSupplier.get();
}
finally {
if (outerBean != null) {
// 设置原当前线程正在创建的 Bean 的名称到当前线程变量中
this.currentlyCreatedBean.set(outerBean);
}
else {
this.currentlyCreatedBean.remove();
}
}
// 未创建 Bean 对象,则创建 NullBean 空对象
if (instance == null) {
instance = new NullBean();
}
// <2> 将实例对象封装成 BeanWrapper 对象
BeanWrapper bw = new BeanWrapperImpl(instance);
// <3> 初始化这个 BeanWrapper 对象
initBeanWrapper(bw);
return bw;
}
过程如下:
- 调用 Supplier 接口的
get()
,返回instance
实例对象 - 将
instance
封装成 BeanWrapper 对象bw
- 对
bw
进行初始化,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
整个过程比较简单
instantiateUsingFactoryMethod 方法
通过 factoryMethodName
工厂方法创建一个实例对象,例如 XML 配置的 factory-method
属性或者 @Bean
标注的方法都会解析成 factoryMethodName
属性
这个过程非常复杂,你可以理解为去找到最匹配的 Method 工厂方法,获取相关入参(依赖注入),然后调用该方法返回一个实例对象(反射机制),方法如下:
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
创建 ConstructorResolver 对象,然后调用其 instantiateUsingFactoryMethod(...)
方法,如下:
// ConstructorResolver.java
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 构造 BeanWrapperImpl 对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 BeanWrapperImpl,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
this.beanFactory.initBeanWrapper(bw);
// -------------------------获取工厂方法的相关信息-------------------------
// <1> 获取工厂方法的相关信息
// 工厂方法所在类对应的 Bean(静态方法不会有)
Object factoryBean;
// 工厂方法所在类的 Class 对象
Class<?> factoryClass;
// 是否为 static 修饰的静态方法
boolean isStatic;
// 获取工厂方法所在类对应的 Bean 的名称(静态方法不会有)
String factoryBeanName = mbd.getFactoryBeanName();
// <1.1> 非静态方法
if (factoryBeanName != null) {
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
// 获取工厂方法所在类对应的 Bean,不然无法调用工厂方法
factoryBean = this.beanFactory.getBean(factoryBeanName);
// 如果是单例模式,已经存在对应的 Bean,则抛出重复创建的异常
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
factoryClass = factoryBean.getClass();
isStatic = false;
}
// <1.2> 静态方法
else {
// It's a static factory method on the bean class.
// 静态方法没有找到对应的 Class 对象无法被调用,则抛出异常
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
// -------------------------尝试获取工厂方法对象和入参-------------------------
// <2> 尝试获取工厂方法对象和参数
// 工厂方法对象
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 方法参数
Object[] argsToUse = null;
// <2.1> 如果方法入参指定了参数,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// <2.2> 否则,尝试从 RootBeanDefinition 中获取已解析出来的工厂方法和入参
else {
Object[] argsToResolve = null;
// 因为可能前面解析了,会临时缓存,避免再次解析
synchronized (mbd.constructorArgumentLock) { // 加锁
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
// 如果工厂方法被解析了,那么参数也可能解析过
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 没有解析过的参数,则尝试从 RootBeanDefinition 中获取未被解析过的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果获取到了未被解析过的入参,则进行解析
if (argsToResolve != null) {
// 处理参数值,类型转换,例如给定方法 A(int, int),配置了 A("1"、"2") 两个参数,则会转换为 A(1, 1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
// -------------------------找到所有匹配的工厂方法-------------------------
// <3> 如果上一步没有找到工厂方法对象或方法入参集合,则需要进行接下来的解析过程,首先找到所有匹配的工厂方法
if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
// <3.1> 获取工厂方法所在的类的实例 Class 对象,因为可能是 Cglib 提升过的子类
factoryClass = ClassUtils.getUserClass(factoryClass);
// <3.2> 获取工厂方法所在的类中所有方法对象
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
// <3.3> 找到这个类中匹配的工厂方法
List<Method> candidateList = new ArrayList<>();
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic // 是否和 `isStatic` 匹配
&& mbd.isFactoryMethod(candidate)) { // 和定义的工厂方法的名称是否相等
candidateList.add(candidate);
}
}
// <3.4> 如果只有一个匹配的方法,且这个方法没有给指定的入参,且本身也没有定义参数,且这个方法没有定义入参
// 则直接调用这个方法创建一个实例对象(反射机制),并返回
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// -------------------------开始找最匹配的工厂方法-------------------------
// <4> 开始找最匹配的工厂方法
// 将匹配的工厂方法转换成数组
Method[] candidates = candidateList.toArray(new Method[0]);
// 将匹配的方法进行排序,public 方法优先,入参个数多的优先
AutowireUtils.sortFactoryMethods(candidates);
// 用于承载解析后的方法参数值
ConstructorArgumentValues resolvedValues = null;
// 是否是构造器注入
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
// 匹配方法的集合
Set<Method> ambiguousFactoryMethods = null;
// -------------------------确定方法参数的入参数量-------------------------
// <5> 确定方法参数的入参数量,匹配的方法的入参数量要多余它
// 方法的参数数量的最小值
int minNrOfArgs;
// <5.1> 如果当前方法指定了入参,则使用其个数作为最小值
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
// <5.1> 否则,从 RootBeanDefinition 解析出方法的参数个数作为最小值
else {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
// RootBeanDefinition 定义了参数值
if (mbd.hasConstructorArgumentValues()) {
// 方法的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析定义的参数值,放入 `resolvedValues` 中,并返回参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {
minNrOfArgs = 0;
}
}
// 记录 UnsatisfiedDependencyException 异常的集合
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历匹配的方法
for (Method candidate : candidates) {
// 方法体的参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
// -------------------------解析出工厂方法的入参-------------------------
// <6> 解析出工厂方法的入参
// 保存参数的对象
ArgumentsHolder argsHolder;
// <6.1> 如果当前方法指定了入参,则直接使用
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
// 显示给定参数,参数长度必须完全匹配
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 根据参数创建参数持有者 ArgumentsHolder 对象
argsHolder = new ArgumentsHolder(explicitArgs);
}
// <6.2> 否则,通过**依赖注入**获取入参
else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
// 为提供参数,解析构造参数
try {
String[] paramNames = null;
// 获取 ParameterNameDiscoverer 参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
// 获取方法的参数名称
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
// 解析出方法的入参,参数值会被依赖注入
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
// 若发生 UnsatisfiedDependencyException 异常,添加到 causes 中。
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// -------------------------根据权重获取最匹配的方法-------------------------
// <7> 因为会遍历所有匹配的方法,所以需要进行权重的判断,拿到最优先的那个
// 判断解析构造函数的时候是否以宽松模式还是严格模式,默认为 true
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
// 代表最匹配的结果,则选择作为符合条件的方法
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
// 如果具有相同参数数量的方法具有相同的类型差异权重,则收集此类型选项
// 但是,仅在非宽松构造函数解析模式下执行该检查,并显式忽略重写方法(具有相同的参数签名)
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
// 查找到多个可匹配的方法
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
// <8> 没有找到对应的工厂方法,则抛出异常
if (factoryMethodToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
// <9> 将解析出来的工厂方法和入参缓存,设置到 RootBeanDefinition 中,因为整个过程比较复杂,避免再次解析
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
Assert.state(argsToUse != null, "Unresolved factory method arguments");
// <10> 调用工厂方法创建一个实例对象(反射机制),并设置到 `bw` 中
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
这个方法我真的是吐了😢,也太长了吧,硬着头皮看完了一部分,参考文件:ConstructorResolver.java
对于过程不感兴趣的可以跳过直接看下面的概括,过程大致如下:
先创建一个 BeanWrapperImpl 对象 bw
,并初始化,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
- 获取工厂方法的相关信息,根据 RootBeanDefinition 的
factoryBeanName
属性判断是否为静态方法,这个属性表示这个工厂方法所在类对应 Bean 的名称,当然静态方法“不属于”这个 Bean,所以它的这个属性为空factoryBeanName
属性不为空,表示不是静态方法,则需要根据factoryBeanName
找到(依赖查找)对应的 Bean,作为factoryBean
- 否则,就是静态方法,获取所在类的 Class 对象即可
这一步找到了三个对象:factoryBean
(工厂方法所在类对应的 Bean,静态方法不会有)、factoryClass
(工厂方法所在类的 Class 对象)、isStatic
(是否为静态方法)。所以想要通过工厂方法获取一个 Bean,则需要方法所在类对应的 Bean 先初始化,然后才能调用这个方法创建 Bean;而静态方法就不用,因为它可以根据所在类的 Class 对象就能调用这个方法创建 Bean,这就是两者的区别。
-
尝试获取工厂方法 Method 对象和入参
-
如果方法入参指定了参数,则直接使用
-
否则,尝试从 RootBeanDefinition 中获取已解析出来的工厂方法和入参,如果获取到了未被解析过的入参,则进行解析(类型转换)
例如给定方法 A(int, int),配置了 A("1"、"2") 两个参数,则会转换为 A(1, 1)
-
这一步尝试获取两个对象:factoryMethodToUse
(对应的工厂方法 Method)、argsToUse
(工厂方法的入参集合)
- 如果上一步没有找到工厂方法对象或方法入参集合,找到所有匹配的工厂方法,首先找到所有匹配的工厂方法
- 获取工厂方法所在的类的实例 Class 对象,因为可能是 Cglib 提升过的子类
- 获取工厂方法所在的类中所有方法对象
- 找到这个类中匹配的工厂方法,是否和
isStatic
匹配,并且和定义的工厂方法的名称是否相等 - 如果只有一个匹配的方法,且这个方法没有给指定的入参,且本身也没有定义参数,且这个方法没有定义入参,则直接调用这个方法创建一个实例对象(反射机制),并返回
上面第 3.3
步找到的通常只有一个,如果没有入参则可以直接进入第 3.4
步,使用这个方法创建一个实例对象。不过你可能定义了重载方法,也可能定义了方法参数,所以需要进行接下来的解析过程
- 开始找最匹配的工厂方法,先排序,public 方法优先,入参个数多的优先
- 确定方法参数的入参数量,匹配的方法的入参数量要多余它
- 如果当前方法指定了入参,则使用其个数作为最小值
- 否则,从 RootBeanDefinition 解析出方法的参数个数作为最小值,没有定义则设置为 0
这一步主要是确定入参的个数,并排序所有匹配的方法,接下来会遍历所有匹配的方法
- 解析出工厂方法的入参
- 如果当前方法指定了入参,则直接使用
- 否则,通过依赖注入获取入参
这一步会找到这个方法的入参,依赖注入的方式
- 因为会遍历所有匹配的方法,所以需要进行权重的判断,拿到最优先的那个
通常情况下,我们只有一个匹配的方法,如果存在多个,会根据方法的参数类型进行权重
- 没有找到对应的工厂方法,则抛出异常
- 将解析出来的工厂方法和入参缓存,设置到 RootBeanDefinition 中,因为整个过程比较复杂,避免再次解析
会缓存这几个数据:resolvedConstructorOrFactoryMethod
(已经解析出来的工厂方法)、constructorArgumentsResolved
(方法入参已经解析出来了 true)、resolvedConstructorArguments
(解析出来的入参)
- 调用工厂方法创建一个实例对象(反射机制),并设置到
bw
中
上面整个过程非常复杂,这里进行简单概括:
-
找到对应的工厂方法,如果是非静态方法,则需要先依赖查找到所在类对应的 Bean,因为需要根据这个 Bean 去调用对应的工厂方法,而静态方法不用,可以根据其 Class 对象调用对应的工厂方法
-
如果工厂方法有入参,则需要注入相关对象(依赖注入)
-
调用这个方法(反射机制),返回一个实例对象
autowireConstructor 方法
这个过程和上一个方法一样非常复杂,不过差不太多,你可以理解为去找到当前 Bean 的构造方法,获取相关入参(构造器注入),然后调用该构造方法返回一个实例对象(反射机制),方法如下:
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
创建 ConstructorResolver 对象,然后调用其 autowireConstructor(...)
方法,如下:
// ConstructorResolver.java
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 构造 BeanWrapperImpl 对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 BeanWrapperImpl,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
this.beanFactory.initBeanWrapper(bw);
// -------------------------尝试获取构造方法和入参-------------------------
// <1> 尝试获取构造方法和入参
// 构造方法
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 构造方法的入参集合
Object[] argsToUse = null;
// <1.1> 如果当前方法入参指定了参数,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// <1.2> 否则,尝试从 RootBeanDefinition 中获取已解析出来的构造方法和入参
else {
// 因为可能前面解析了,会临时缓存,避免再次解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 如果构造方法被解析了,那么参数也可能解析过
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 没有解析过的参数,则尝试从 RootBeanDefinition(合并后)中获取未被解析过的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果获取到了未被解析过的入参
if (argsToResolve != null) {
// 处理参数值,类型转换,例如给定方法 A(int, int),配配置了 A("1"、"2") 两个参数,则会转换为 A(1, 1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// -------------------------开始获取构造方法和入参-------------------------
// <2> 如果上一步没有找到构造方法或入参集合,找到所有匹配的工厂方法,首先找到所有匹配的构造方法
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// <2.1> 获取所有的构造方法,如果当前方法指定了构造方法的集合,则使用这个集合
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// <2.2> 如果构造方法只有一个,且当前方法的入参没有指定参数,且本身也没有定义参数,且这个构造方法没有定义入参
// 则直接调用这个构造方法创建一个实例对象(反射机制),并返回
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// Need to resolve the constructor.
// 是否是构造器注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
// 用于承载解析后的方法参数值
ConstructorArgumentValues resolvedValues = null;
// -------------------------确定构造方法的入参数量-------------------------
// <3> 确定构造参数的入参数量,匹配的方法的入参数量要多余它
// 方法的参数数量的最小值
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
// 从 RootBeanDefinition 解析出方法的参数个数作为最小值
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// <4> 将所有的构造方法进行排序,public 方法优先,入参个数多的优先
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历所有构造函数
for (Constructor<?> candidate : candidates) {
// 获取该构造方法的参数类型
Class<?>[] paramTypes = candidate.getParameterTypes();
// 如果前面已经找到匹配的构造方法和入参,则直接结束循环
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 如果这个构造方法的参数个数小于入参数量,则跳过
if (paramTypes.length < minNrOfArgs) {
continue;
}
// -------------------------解析出构造方法的入参-------------------------
// <5> 解析出构造方法的入参
// 保存参数的对象
ArgumentsHolder argsHolder;
// <5.2> 通过**依赖注入**获取入参
if (resolvedValues != null) {
try {
// 获取构造方法的参数名称(@ConstructorProperties 注解)
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
// 没有获取到则通过 ParameterNameDiscoverer 参数探测器获取参数名称
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
// 解析出方法的入参,参数值会被依赖注入
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// <5.1> 如果当前方法的入参指定了参数,如果个数相等则直接使用
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
// -------------------------根据权重获取最匹配的方法-------------------------
// <6> 因为会遍历所有匹配的方法,所以需要进行权重的判断,拿到最优先的那个
// 判断解析构造函数的时候是否以宽松模式还是严格模式,默认为 true
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 代表最匹配的结果,则选择作为符合条件的方法
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
// <7> 没有找到对应的构造方法,则抛出异常
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
// <8> 将解析出来的工厂方法和入参缓存,设置到 RootBeanDefinition 中,因为整个过程比较复杂,避免再次解析
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// <9> 调用这个构造方法返回一个实例对象(反射机制),并设置到 `bw` 中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
这个方法我也是吐了😢,不过还好,和上一个方法逻辑差不多,硬着头皮,参考文件:ConstructorResolver.java
对于过程不感兴趣的可以跳过直接看下面的概括,过程大致如下:
先创建一个 BeanWrapperImpl 对象 bw
,并初始化,设置 ConversionService 类型转换器,并注册自定义的属性编辑器
-
尝试获取构造方法和入参
-
如果当前方法入参指定了参数,则直接使用
-
否则,尝试从 RootBeanDefinition 中获取已解析出来的构造方法和入参,如果获取到了未被解析过的入参,则进行解析(类型转换)
例如给定方法 A(int, int),配置了 A("1"、"2") 两个参数,则会转换为 A(1, 1)
-
这一步尝试获取两个对象:constructorToUse
(构造方法)、argsToUse
(构造方法的入参集合)
-
如果上一步没有找到构造方法或入参集合,找到所有匹配的工厂方法,首先找到所有匹配的构造方法
-
获取所有的构造方法,如果当前方法指定了构造方法的集合,则使用这个集合
-
如果构造方法只有一个,且当前方法的入参没有指定参数,且本身也没有定义参数,且这个构造方法没有定义入参
则直接调用这个构造方法创建一个实例对象(反射机制),并返回
-
上面第 2.2
步,通常只有默认构造方法才会直接调用并返回的,否则需要进行接下来的解析过程
- 确定构造参数的入参数量,匹配的方法的入参数量要多余它
- 将所有的构造方法进行排序,public 方法优先,入参个数多的优先
这一步主要是确定入参的个数,并排序所有匹配的构造方法,接下来会遍历所有匹配的构造方法
如果前面已经找到匹配的构造方法和入参,则直接结束循环;如果这个构造方法的参数个数小于入参数量,则跳过
- 解析出构造方法的入参
- 如果当前方法的入参指定了参数,如果个数相等则直接使用
- 否则,通过构造器注入获取入参
这一步会找到这个构造方法的入参,构造器注入的方式
- 因为会遍历所有匹配的方法,所以需要进行权重的判断,拿到最优先的那个,会根据方法的参数类型进行权重
- 没有找到对应的构造方法,则抛出异常
- 将解析出来的工厂方法和入参缓存,设置到 RootBeanDefinition 中,因为整个过程比较复杂,避免再次解析
会缓存这几个数据:resolvedConstructorOrFactoryMethod
(已经解析出来的构造方法)、constructorArgumentsResolved
(方法入参已经解析出来了 true)、resolvedConstructorArguments
(解析出来的入参)
- 调用这个构造方法返回一个实例对象(反射机制),并设置到
bw
中
上面整个过程非常复杂,这里进行简单概括:
-
找到最匹配的构造方法
-
如果构造方法有入参,则需要注入相关对象(构造器注入,其实也是依赖注入获取到的参数)
-
调用这个构造方法(反射机制),返回一个实例对象
instantiateBean 方法
兜底方法,如果构造方法找不到(或者已经解析出来的构造方法),则直接使用默认的构造方法(或者已经解析出来的构造方法),返回一个实例对象,方法如下:
// AbstractAutowireCapableBeanFactory.java
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>) () ->
// 获得 InstantiationStrategy 对象,并使用它,创建 Bean 对象
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 获得 InstantiationStrategy 对象,并使用它,创建 Bean 对象
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);
}
}
可以看到会通过 CglibSubclassingInstantiationStrategy#instantiate(...)
方法创建一个实例对象,该方法如下:
// SimpleInstantiationStrategy.java
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// <1> 没有 MethodOverride 对象,也就是没有需要覆盖或替换的方法,则直接使用反射机制进行实例化即可
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// <1.1> 尝试从 RootBeanDefinition 获得已经解析出来的构造方法 `resolvedConstructorOrFactoryMethod`
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// <1.2> 没有解析出来的构造方法,则获取默认的构造方法
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
// 如果是接口,抛出 BeanInstantiationException 异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
// 从 clazz 中,获得构造方法
if (System.getSecurityManager() != null) { // 安全模式
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
// 标记 resolvedConstructorOrFactoryMethod 属性
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// <1.3> 通过这个构造方法实例化一个对象(反射机制)
return BeanUtils.instantiateClass(constructorToUse);
}
// <2> 否则,通过 CGLIB 生成一个子类对象
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
过程大致如下:
- 没有 MethodOverride 对象,也就是没有需要覆盖或替换的方法,则直接使用反射机制进行实例化即可
- 尝试从 RootBeanDefinition 获得已经解析出来的构造方法
resolvedConstructorOrFactoryMethod
- 没有解析出来的构造方法,则获取默认的构造方法
- 通过这个构造方法实例化一个对象(反射机制)
- 尝试从 RootBeanDefinition 获得已经解析出来的构造方法
- 否则,通过 CGLIB 生成一个子类对象,该过程暂时忽略
整个过程并不复杂
总结
当我们显示或者隐式地调用AbstractBeanFactory
的 getBean(...)
方法时,会触发 Bean 的加载,在《开启 Bean 的加载》文章中分析了整个加载过程。
对于不同作用域的 Bean,底层都会调用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法进行创建,在上一篇《Bean 的创建过程》文章中分析了整个创建过程。在创建 Bean 的过程中,需要先创建一个实例对象,这个过程在实例化阶段完成,主要分为下面几种情况:
- 指定了 Supplier 实例化回调接口,则回调该接口,返回一个实例对象
- 配置了
factory-method
工厂方法创建当前 Bean,则找到这个方法,如果有入参,则需要找到对应的参数(依赖注入),然后创建一个实例对象(@Bean
注解底层原理也是这种方式) - 找到一个最匹配的构造方法,如果有入参则需要找到对应的参数(构造器注入),返回一个实例对象,这个构造方法会设置到这个 RootBeanDefinition 中,避免再次解析,提高性能
- 兜底方法,使用默认构造方法返回一个实例对象