文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
1. 概要
- 在 Spring 中存在着不同的 scope,默认是 singleton ,还有 prototype、request 等等其他的 scope 。
- 需要对不同作用域的 Bean 进行实例化,主要分成了三个模块 singleton、原型模式 和 其它作用域,相关可以查看 【Spring 笔记】Bean 加载相关整理。
- 这三个模块都调用了
createBean()
方法,该方法定义在AbstractBeanFactory
中,其含义是根据给定的BeanDefinition
和 args 实例化一个 Bean 对象。- 如果该
BeanDefinition
存在父类,则该BeanDefinition
已经合并了父类的属性。 - 所有 Bean 实例的创建,都会委托给该方法实现。
- 该方法接受三个方法参数。
- 如果该
参数 | 说明 |
---|---|
beanName | bean 的名字。 |
mbd | 已经合并了父类属性的(如果有的话)BeanDefinition 对象。 |
args | 用于构造函数或者工厂方法创建 Bean 实例对象的参数。 |
// AbstractBeanFactory.java
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;
2. 原理
2.1 createBean
- 该抽象方法的默认实现是在类
AbstractAutowireCapableBeanFactory
中实现。
// AbstractAutowireCapableBeanFactory.java
@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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 1. 确保此时的 bean 已经被解析了
// 如果获取的class 属性不为null,则克隆该 BeanDefinition
// 主要是因为该动态解析的 class 无法保存到到共享的 BeanDefinition
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2. 验证和准备覆盖方法
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. 实例化的前置处理
// 给 BeanPostProcessors 一个机会用来返回一个代理类而不是真正的类实例
// AOP 的功能就是基于这个地方
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,解析指定
BeanDefinition
的 class 属性。 - 步骤 2,处理 override 属性。
- 步骤 3,实例化的前置处理。
- 步骤 4,创建 Bean 对象。
-
步骤 1,解析指定
2.1.1 解析指定 BeanDefinition 的 class
- 将已经解析的 Class 存储在 bean definition 中供后续使用。
- 如果解析的 class 不为空,则会将该
BeanDefinition
进行设置到 mbdToUse 中。因为动态解析的 class 无法保存到共享的BeanDefinition
中。
- 如果解析的 class 不为空,则会将该
// AbstractAutowireCapableBeanFactory.java
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
resolveBeanClass
// AbstractAutowireCapableBeanFactory.java
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
//如果数据结构中存在BeanClass直接返回
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
//没有会委派给下面方法
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);
}
}
doResolveBeanClass
// AbstractAutowireCapableBeanFactory.java
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
//获取类加载器对象
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader classLoaderToUse = beanClassLoader;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
classLoaderToUse = tempClassLoader;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
//下面获取类对象第一种为className不为空
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
return ClassUtils.forName((String) evaluated, classLoaderToUse);
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (classLoaderToUse != beanClassLoader) {
return ClassUtils.forName(className, classLoaderToUse);
}
}
//如果className为空
return mbd.resolveBeanClass(beanClassLoader);
}
2.1.2 处理 override 属性
- 主要就是为了处理 lookup-method 和 replace-method 这两个配置功能,主要是将这两个配置存放在
BeanDefinition
中的 methodOverrides 属性中,相关可以查看 【Spring 笔记】Bean 解析相关整理 中的分析。 - 在 bean 实例化的过程中如果检测到存在 methodOverrides,则会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 做 增强处理,实现方法为
mbdToUse.prepareMethodOverrides()
。
/ AbstractBeanDefinition.java
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
if (hasMethodOverrides()) {
Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
synchronized (overrides) { // 同步
// 循环,执行 prepareMethodOverride
for (MethodOverride mo : overrides) {
prepareMethodOverride(mo);
}
}
}
}
- 获取所有的 override method ,然后通过迭代的方法调用
prepareMethodOverride(MethodOverride mo)
方法。
// AbstractBeanDefinition.java
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
} else if (count == 1) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
- 对 methodOverrides 属性做了一些简单的校验,方法的调用流程。
- 根据方法名称,从 class 中获取该方法名的个数。
- 如果个数为 0 ,则抛出
BeanDefinitionValidationException
异常。 - 如果个数为 1 ,则设置该重载方法 没有被重载(overloaded = false),在后续调用时,可以直接找到方法而不需要进行方法参数的校验。
- 若存在多个重载方法,则在方法调用时需要根据参数类型判断到底重载的是哪个方法。
- 如果个数为 0 ,则抛出
- 根据方法名称,从 class 中获取该方法名的个数。
2.1.3 实例化的前置处理
-
resolveBeforeInstantiation()
方法的作用,是给BeanPostProcessors
后置处理器返回一个代理对象的机会。
// AbstractBeanDefinition.java
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
- 如果代理对象不为空,则直接返回代理对象,Spring 实现 AOP 就是基于这个判断。
// AbstractAutowireCapableBeanFactory.java
@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;
}
-
applyBeanPostProcessorsBeforeInstantiation()
为 实例化前 的后处理器应用。 -
applyBeanPostProcessorsAfterInitialization()
为 实例化后 的后处理器应用。
2.1.4 创建 Bean
- 没有代理对象,直接进行 bean 的创建。
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器
BeanWrapper instanceWrapper = null;
// 1. 单例模型,则从未完成的 FactoryBean 缓存中删除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 2. 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 包装的实例对象
final Object bean = instanceWrapper.getWrappedInstance();
// 包装的实例对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 3. 判断是否有后置处理
// 如果有后置处理,则允许后置处理修改 BeanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 后置处理修改 BeanDefinition
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.
// 4. 解决单例模式的循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() // 单例模式
&& this.allowCircularReferences // 运行循环依赖
&& isSingletonCurrentlyInCreation(beanName)); // 当前单例 bean 是否正在被创建
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 提前将创建的 bean 实例加入到 singletonFactories 中
// 这里是为了后期避免循环依赖
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 开始初始化 bean 实例对象
Object exposedObject = bean;
try {
// 5. 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性
// 则会递归初始依赖 bean
populateBean(beanName, mbd, instanceWrapper);
// 6. 调用初始化方法
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);
}
}
// 7. 循环依赖处理
if (earlySingletonExposure) {
// 获取 earlySingletonReference
Object earlySingletonReference = getSingleton(beanName, false);
// 只有在存在循环依赖的情况下,earlySingletonReference 才不会为空
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 8. 注册 bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 方法的调用流程。
- 步骤 1,如果是单例模式,则清除缓存。
-
步骤 2,实例化 bean ,将
BeanDefinition
转换为 org.springframework.beans.BeanWrapper 对象。 -
步骤 3,
MergedBeanDefinitionPostProcessor
的应用。 - 步骤 4,单例模式的循环依赖处理。
-
步骤 5,调用
populateBean()
方法进行属性填充,将所有属性填充至 bean 的实例中。 -
步骤 6,调用
initializeBean()
方法,初始化 bean 。 - 步骤 7,依赖检查。
-
步骤 8,注册
DisposableBean
。
2.1.4.1 实例化 bean
- 实例化 bean,对应的方法为
createBeanInstance()
,就是 选择合适实例化策略 为 bean 创建实例对象,具体的策略有。- Supplier 回调方式。
- 工厂方法初始化。
- 构造函数自动注入初始化。
- 默认构造函数注入。
- 其中,工厂方法初始化和构造函数自动注入初始化两种方式最为复杂,主要是因为构造函数和构造参数的不确定性,Spring 需要花大量的精力来确定构造函数和构造参数。
- 在实例化的时候,会根据是否有需要覆盖或者动态替换的方法,如果存在覆盖或者动态替换,选择 CGLIB 方式实例化,否则直接利用反射的方式。
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析 bean ,将 bean 类名解析为 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());
}
// 1. 如果存在 Supplier 回调,则使用给定的回调方法初始化策略
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 2. 使用 FactoryBean 的 factory-method 来创建,支持静态工厂和实例工厂
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 3. Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
// constructorArgumentLock 构造函数的常用锁
synchronized (mbd.constructorArgumentLock) {
// 如果已缓存的解析的构造函数或者工厂方法不为空,则可以利用构造函数解析
// 因为需要根据参数确认到底使用哪个构造函数,该过程比较消耗性能,所有采用缓存机制
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 已经解析好了,直接注入即可
if (resolved) {
// 3.1 autowire 自动注入,调用构造函数自动注入
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
} else {
// 3.2 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 4. 确定解析的构造函数
// 主要是检查已经注册的 SmartInstantiationAwareBeanPostProcessor
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 4.1 有参数情况时,创建 Bean 。先利用参数个数,类型等,确定最精确匹配的构造方法。
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
// 4.1 选择构造方法,创建 Bean。
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null); // args = null
}
// No special handling: simply use no-arg constructor.
// 4.2 有参数时,又没获取到构造方法,则只能调用无参构造方法来创建实例。
return instantiateBean(beanName, mbd);
}
- 实例化 Bean 对象方法的调用流程。
-
步骤 1,如果存在
Supplier
回调,则调用obtainFromSupplier()
方法,进行初始化。 -
步骤 2,如果存在工厂方法,则使用工厂方法进行初始化,主要实现是
instantiateUsingFactoryMethod()
方法。 -
步骤 3,判断缓存,缓存中存在,则直接使用已经解析的处理。根据
constructorArgumentsResolved
参数来判断。-
步骤 3.1,使用构造函数自动注入,调用
autowireConstructor()
方法。 -
步骤 3.2,默认构造函数,调用
instantiateBean()
方法。
-
步骤 3.1,使用构造函数自动注入,调用
-
步骤 4,缓存中没有,先确定使用哪个构造函数完成解析工作(一个类有多个构造函数,每个构造函数都有不同的构造参数),需要根据参数锁定构造函数并完成初始化。
-
步骤 4.1,如果存在参数,则使用相应的带有参数的构造函数,调用
autowireConstructor()
方法。 -
步骤 4.2,否则,使用默认构造函数,调用
instantiateBean()
方法。
-
步骤 4.1,如果存在参数,则使用相应的带有参数的构造函数,调用
-
步骤 1,如果存在
2.1.4.1.1 obtainFromSupplier
- 从
BeanDefinition
中获取Supplier
对象。如果不为空,则调用obtainFromSupplier()
方法。
// AbstractAutowireCapableBeanFactory.java
// protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
Supplier
- java.util.function.Supplier 接口。
public interface Supplier<T> {
T get();
}
- 如果设置了这样的回调,那么其他的构造器或者工厂方法都会没有用。
// AbstractBeanDefinition.java
/**
* 创建 Bean 的 Supplier 对象
*/
@Nullable
private Supplier<?> instanceSupplier;
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
- 在构造
BeanDefinition
对象时,设置了该值(instanceSupplier)。
// RootBeanDefinition.java
public <T> RootBeanDefinition(@Nullable Class<T> beanClass, String scope, @Nullable Supplier<T> instanceSupplier) {
super();
setBeanClass(beanClass);
setScope(scope);
// 设置 instanceSupplier 属性
setInstanceSupplier(instanceSupplier);
}
- 如果设置了 instanceSupplier 属性,则可以调用
obtainFromSupplier()
方法,完成 Bean 的初始化。
// AbstractAutowireCapableBeanFactory.java
/**
* 当前线程,正在创建的 Bean 对象的名字
*
* The name of the currently created bean, for implicit dependency registration
* on getBean etc invocations triggered from a user-specified Supplier callback.
*/
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
// 获得原创建的 Bean 的对象名
String outerBean = this.currentlyCreatedBean.get();
// 设置新的 Bean 的对象名,到 currentlyCreatedBean 中
this.currentlyCreatedBean.set(beanName);
try {
// 1. 调用 Supplier 的 get(),返回一个 Bean 对象
instance = instanceSupplier.get();
} finally {
// 设置原创建的 Bean 的对象名,到 currentlyCreatedBean 中
if (outerBean != null) {
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;
}
- 方法的调用流程。
-
步骤 1,调用
Supplier
的get()
方法,获得一个 Bean 实例对象。 -
步骤 2,根据该实例对象构造一个
BeanWrapper
对象。 - 步骤 3,初始化该对象。
-
步骤 1,调用
2.1.4.1.2 instantiateUsingFactoryMethod
- 如果存在工厂方法,则调用
instantiateUsingFactoryMethod()
方法完成 bean 的初始化工作。
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
ConstructorResolver
- org.springframework.expression.ConstructorResolver 是构造方法或者工厂类初始化 bean 的委托类。
// ConstructorResolver.java
public BeanWrapper instantiateUsingFactoryMethod (
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 构造 BeanWrapperImpl 对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 BeanWrapperImpl
// 向BeanWrapper对象中添加 ConversionService 对象和属性编辑器 PropertyEditor 对象
this.beanFactory.initBeanWrapper(bw);
// 1. 获得 factoryBean、factoryClass、isStatic、factoryBeanName 属性
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
String factoryBeanName = mbd.getFactoryBeanName();
// 工厂名不为空
if (factoryBeanName != null) {
if (factoryBeanName.equals(beanName)) { // 抛出 BeanDefinitionStoreException 异常
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
// 获取工厂实例
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) { // 抛出 ImplicitlyAppearedSingletonException 异常
throw new ImplicitlyAppearedSingletonException();
}
factoryClass = factoryBean.getClass();
isStatic = false;
} else {
// 工厂名为空,则其可能是一个静态工厂
// 静态工厂创建bean,必须要提供工厂的全类名
// It's a static factory method on the bean 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. 获得 factoryMethodToUse、argsHolderToUse、argsToUse 属性
Method factoryMethodToUse = null; // 工厂方法
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null; // 参数
// 2.1 如果指定了构造参数则直接使用
// 在调用 getBean 方法的时候指定了方法参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
// 没有指定,则尝试从配置文件中解析
Object[] argsToResolve = null;
// 2.2 首先尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
// 获取缓存中的构造函数或者工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
// 获取缓存中的构造参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 获取缓存中的构造函数参数的包可见字段
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 缓存中存在,则解析存储在 BeanDefinition 中的参数
// 如给定方法的构造函数 A(int ,int ),则通过此方法后就会把配置文件中的("1","1")转换为 (1,1)
// 缓存中的值可能是原始值也有可能是最终值
if (argsToResolve != null) {
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.
// 获取工厂方法的类全名称
factoryClass = ClassUtils.getUserClass(factoryClass);
// 获取所有待定方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
// 检索所有方法,这里是对方法进行过滤
List<Method> candidateList = new ArrayList<>();
for (Method candidate : rawCandidates) {
// 如果有static 且为工厂方法,则添加到 candidateSet 中
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidateList.add(candidate);
}
}
// 创建 Bean
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
Method[] candidates = candidateList.toArray(new Method[0]);
// 排序构造函数
// public 构造函数优先参数数量降序,非 public 构造函数参数数量降序
AutowireUtils.sortFactoryMethods(candidates);
// 用于承载解析后的构造函数参数的值
ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} 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.
// 2.3 getBean() 没有传递参数,则需要解析保存在 BeanDefinition 构造函数中指定的参数
if (mbd.hasConstructorArgumentValues()) {
// 构造函数的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析构造函数的参数
// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
} else {
minNrOfArgs = 0;
}
}
LinkedList<UnsatisfiedDependencyException> causes = null; // 记录 UnsatisfiedDependencyException 异常的集合
// 遍历 candidates 数组
for (Method candidate : candidates) {
// 方法体的参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
// 保存参数的对象
ArgumentsHolder argsHolder;
// #getBean(...) 传递了参数
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
// 显示给定参数,参数长度必须完全匹配
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 根据参数创建参数持有者 ArgumentsHolder 对象
argsHolder = new ArgumentsHolder(explicitArgs);
} else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
// 为提供参数,解析构造参数
try {
String[] paramNames = null;
// 获取 ParameterNameDiscoverer 对象
// ParameterNameDiscoverer 是用于解析方法和构造函数的参数名称的接口,为参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
// 获取指定构造函数的参数名称
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
// 在已经解析的构造函数参数值的情况下,创建一个参数持有者 ArgumentsHolder 对象
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; // continue ,继续执行
}
}
// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// 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);
}
}
}
// 没有可执行的工厂方法,抛出异常
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);
}
if (explicitArgs == null && argsHolderToUse != null) {
// 将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
// 创建 Bean 对象,并设置到 bw 中
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
private Object instantiate(
String beanName, RootBeanDefinition mbd, Constructor constructorToUse, Object[] argsToUse) {
try {
InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
this.beanFactory.getAccessControlContext());
} else {
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
- 该方法主要完成确定工厂对象,然后获取构造函数和构造参数,最后调用
InstantiationStrategy
对象instantiate() 方法
,创建 Bean 实例。 - 方法的调用流程。
-
步骤 1,获取工厂方法名。
- 若工厂方法名不为空,则调用
AbstractAutowireCapableBeanFactory#getBean()
方法,获取工厂对象。 - 若为空,则可能为一个静态工厂,对于静态工厂则必须提供工厂类的全类名,同时设置 factoryBean = null。
- 若工厂方法名不为空,则调用
-
步骤 2,构造参数确认,主要分为三种情况(explicitArgs 参数、缓存中获取、配置文件中解析)。
-
步骤 2.1,explicitArgs 参数,是调用
getBean()
方法时传递。一般该参数就是用于初始化 Bean 时所传递的参数。如果该参数不为空,则可以确定构造函数的参数就是它。 -
步骤 2.2,从缓存中获取,
instantiateUsingFactoryMethod()
方法的最后,会通过argsHolderToUse.storeCache(mbd, factoryMethodToUse)
方法将构造函数、构造参数保存到缓存中。
-
步骤 2.1,explicitArgs 参数,是调用
-
步骤 1,获取工厂方法名。
// ConstructorResolver.ArgumentsHolder.java
public void storeCache(RootBeanDefinition mbd, Executable constructorOrFactoryMethod) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
mbd.constructorArgumentsResolved = true;
if (this.resolveNecessary) {
mbd.preparedConstructorArguments = this.preparedArguments;
} else {
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
// RootBeanDefinition.java
/** Common lock for the four constructor fields below. */
final Object constructorArgumentLock = new Object(); // 构造函数的缓存锁
/** Package-visible field for caching the resolved constructor or factory method. */
@Nullable
Executable resolvedConstructorOrFactoryMethod; // 缓存已经解析的构造函数或者工厂方法
/** Package-visible field that marks the constructor arguments as resolved. */
boolean constructorArgumentsResolved = false; // 标记字段,标记构造函数、参数已经解析了。默认为 `false` 。
/** Package-visible field for caching fully resolved constructor arguments. */
@Nullable
Object[] resolvedConstructorArguments; // 缓存已经解析的构造函数参数,包可见字段。
/** Package-visible field for caching partly prepared constructor arguments. */
@Nullable
Object[] preparedConstructorArguments;
- 其中涉及到的几个参数,都跟构造函数、构造函数缓存有关。
参数 | 说明 |
---|---|
constructorArgumentLock | 构造函数的缓存锁。 |
resolvedConstructorOrFactoryMethod | 缓存已经解析的构造函数或者工厂方法。 |
constructorArgumentsResolved | 标记字段,标记构造函数、参数已经解析了。默认为 false 。 |
resolvedConstructorArguments | 缓存已经解析的构造函数参数,包可见字段 。 |
preparedConstructorArguments | 缓存部分准备的构造函数参数,包可见字段。 |
- 从缓存中获取就是提取这几个参数的值。
// ConstructorResolver.java
// 没有指定,则尝试从配置文件中解析
Object[] argsToResolve = null;
// 2.2 首先尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
// 获取缓存中的构造函数或者工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
// 获取缓存中的构造参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 获取缓存中的构造函数参数的包可见字段
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 缓存中存在,则解析存储在 BeanDefinition 中的参数
// 如给定方法的构造函数 A(int ,int ),则通过此方法后就会把配置文件中的("1","1")转换为 (1,1)
// 缓存中的值可能是原始值也有可能是最终值
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
-
如果缓存中存在构造参数,则需要调用
resolvePreparedArguments()
方法,进行转换。- 因为缓存中的值有可能是最终值,也有可能不是最终值。比如构造函数中的类型为 Integer 类型的 1,但是原始的参数类型有可能是 String 类型的 "1" ,所以即便是从缓存中得到了构造参数,也需要经过类型转换确保参数类型完全对应。
-
步骤 2.3,配置文件中解析,即没有通过传递参数的方式传递构造参数,缓存中也没有,就只能通过解析配置文件获取构造参数。
- 因为配置文件中的信息都会转换到
BeanDefinition
实例对象中,所以配置文件中的参数可以直接通过BeanDefinition
对象获取。
- 因为配置文件中的信息都会转换到
// AbstractAutowireCapableBeanFactory.java
// 2.3. getBean() 没有传递参数,则需要解析保存在 BeanDefinition 构造函数中指定的参数
if (mbd.hasConstructorArgumentValues()) {
// 2.3.1. 构造函数的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 2.3.2. 解析构造函数的参数
// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
-
步骤 2.3.1,通过
BeanDefinition
的getConstructorArgumentValues()
方法,获取构造信息。 -
步骤 2.3.2,获取的参数信息包括直接值和引用,交由
resolveConstructorArguments()
方法完成。- 该方法会将构造参数信息解析为 resolvedValues 对象,并返回解析到的参数个数 minNrOfArgs。
-
步骤 3,构造函数。
- 通过
getCandidateMethods()
方法,获取所有的构造方法,同时对构造方法进行筛选。 - 进行排序处理(
AutowireUtils.sortFactoryMethods()
)。排序的主要目的,是为了能够更加方便的找到匹配的构造函数,因为构造函数的确认是根据参数个数确认的。排序的规则是 先按照 public / 非 public 构造函数升序,再按照构造参数数量降序。 - 通过迭代 candidates(包含了所有要匹配的构造函数)的方式,依次比较其参数。
- 如果显示提供了参数(explicitArgs != null),则直接比较两者长度是否相等,如果相等则表示找到,否则继续比较。
- 如果没有显示提供参数,则需要获取 org.springframework.core.ParameterNameDiscoverer 对象,该对象为 参数名称探测器,主要用于发现方法和构造函数的参数名称。
- 将参数包装成
ConstructorResolver.ArgumentsHolder
对象,该对象用于保存参数,称之为参数持有者。将对象包装成ArgumentsHolder
对象后,可以通过它来进行构造函数匹配。匹配分为 严格模式 和 宽松模式。- 严格模式:解析构造函数时,必须所有参数都需要匹配,否则抛出异常。
- 宽松模式:使用具有 " 最接近的模式 " 进行匹配。
- 判断的依据是根据
BeanDefinition
的 isLenientConstructorResolution 属性(该参数是构造AbstractBeanDefinition
对象时传递)来获取类型差异权重(typeDiffWeight)。- 如果 typeDiffWeight < minTypeDiffWeight,则代表 " 最接近的模式 ",选择其作为构造函数。
- 否则,只有两者具有相同的参数数量,且类型差异权重相等才会纳入考虑范围。
- 通过
-
步骤 4,org.springframework.beans.factory.support.InstantiationStrategy 对象的
instantiate()
方法,创建 bean 实例。
// SimpleInstantiationStrategy.java
/**
* 线程变量,正在创建 Bean 的 Method 对象
*/
private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<>();
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
try {
// 设置 Method 可访问
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
} else {
ReflectionUtils.makeAccessible(factoryMethod);
}
// 获得原 Method 对象
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
// 设置新的 Method 对象,到 currentlyInvokedFactoryMethod 中
currentlyInvokedFactoryMethod.set(factoryMethod);
// 1. 创建 Bean 对象
Object result = factoryMethod.invoke(factoryBean, args);
// 未创建,则创建 NullBean 对象
if (result == null) {
result = new NullBean();
}
return result;
} finally {
// 设置老的 Method 对象,到 currentlyInvokedFactoryMethod 中
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
} else {
currentlyInvokedFactoryMethod.remove();
}
}
} catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(factoryMethod,
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
} catch (IllegalAccessException ex) {
throw new BeanInstantiationException(factoryMethod,
"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
} catch (InvocationTargetException ex) {
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
"declaring the factory method as static for independence from its containing instance. " + msg;
}
throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
}
}
- 利用 Java 反射执行工厂方法并返回创建好的实例。
2.1.4.1.3 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.java
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 封装 BeanWrapperImpl 对象,并完成初始化
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 获得 constructorToUse、argsHolderToUse、argsToUse
Constructor<?> constructorToUse = null; // 构造函数
ArgumentsHolder argsHolderToUse = null; // 构造参数
Object[] argsToUse = null; // 构造参数
// 确定构造参数
// 如果 getBean() 已经传递,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
} 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) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 缓存中存在,则解析存储在 BeanDefinition 中的参数
// 如给定方法的构造函数 A(int ,int ),则通过此方法后就会把配置文件中的("1","1")转换为 (1,1)
// 缓存中的值可能是原始值也有可能是最终值
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// 没有缓存,则尝试从配置文件中获取参数
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// 如果 chosenCtors 未传入,则获取构造方法们
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);
}
}
// 创建 Bean
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;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} else {
// 从 BeanDefinition 中获取构造参数,也就是从配置文件中提取构造参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析构造函数的参数
// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 对构造函数进行排序处理
// public 构造函数优先参数数量降序,非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.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;
}
// 参数持有者 ArgumentsHolder 对象
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
// 注释上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
// 获取构造函数、方法参数的探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 通过探测器获取构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 根据构造函数和构造参数,创建参数持有者 ArgumentsHolder 对象
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
} catch (UnsatisfiedDependencyException ex) {
// 若发生 UnsatisfiedDependencyException 异常,添加到 causes 中。
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; // continue ,继续执行
}
} else {
// continue 构造函数没有参数
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 根据 explicitArgs ,创建 ArgumentsHolder 对象
argsHolder = new ArgumentsHolder(explicitArgs);
}
// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// 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);
}
}
// 没有可执行的工厂方法,抛出异常
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);
}
if (explicitArgs == null) {
// 将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
// 创建 Bean 对象,并设置到 bw 中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
- 首先确定构造函数参数、构造函数,然后调用相应的初始化策略进行 bean 的初始化,其中部分逻辑和
instantiateUsingFactoryMethod()
方法,基本一致。
instantiate
- 首先,获取实例化 Bean 的策略
InstantiationStrategy
对象。然后,调用其instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Constructor<?> ctor, Object... args)
方法,该方法在SimpleInstantiationStrategy
中实现。
//InstantiationStrategy.java
public interface InstantiationStrategy {
/**
* 默认的构造方法
* @param bd
* @param beanName
* @param owner
* @return
* @throws BeansException
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)throws BeansException;
/**
* 指定构造方法
* @param bd
* @param beanName
* @param owner
* @param ctor
* @param args
* @return
* @throws BeansException
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) throws BeansException;
/**
* 通过指定的工厂方法
* @param bd
* @param beanName
* @param owner
* @param factoryBean
* @param factoryMethod
* @param args
* @return
* @throws BeansException
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, Method factoryMethod, Object... args)
throws BeansException;
// SimpleInstantiationStrategy.java
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
// 1. 没有覆盖,直接使用反射实例化即可
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// 设置构造方法,可访问
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
// 通过 BeanUtils 直接使用构造器对象实例化 Bean 对象
return BeanUtils.instantiateClass(ctor, args);
} else {
// 2. 生成 CGLIB 创建的子类对象
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
// BeanUtils.java
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
// 设置构造方法,可访问
ReflectionUtils.makeAccessible(ctor);
// 使用构造方法,创建对象
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
// 各种异常的翻译,最终统一抛出 BeanInstantiationException 异常
} catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
} catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
} catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
} catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
- 方法的调用流程。
- 步骤 1,如果该 bean 没有配置 lookup-method、replaced-method 标签或者 @Lookup 注解,则直接通过反射的方式实例化 Bean 对象。
- 步骤 2,如果存在需要覆盖的方法或者动态替换的方法时,则需要使用 CGLIB 进行动态代理,因为可以在创建代理的同时将动态方法替换类中。
反射创建 Bean 对象
- 调用工具类 BeanUtils 的
instantiateClass()
方法,完成反射工作,创建对象。
CGLIB 创建 Bean 对象
- 默认没有实现,具体过程由其子类 org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy 实现。
// SimpleInstantiationStrategy.java
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
}
// CglibSubclassingInstantiationStrategy.java
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
// 通过CGLIB生成一个子类对象
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
- 创建一个
CglibSubclassCreator
对象,调用其instantiate()
方法,生成其子类对象。
// CglibSubclassingInstantiationStrategy.java
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
// 通过 Cglib 创建一个代理类
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
// 没有构造器,通过 BeanUtils 使用默认构造器创建一个bean实例
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
} else {
try {
// 获取代理类对应的构造器对象,并实例化 bean
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
} catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
// 为了避免 memory leaks 异常,直接在 bean 实例上设置回调对象
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
2.1.4.1.4 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);
}
// 封装 BeanWrapperImpl 并完成初始化
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
instantiate
// SimpleInstantiationStrategy.java
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// 没有覆盖,直接使用反射实例化即可
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获得构造方法 constructorToUse
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
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);
}
}
}
// 通过 BeanUtils 直接使用构造器对象实例化 Bean 对象
return BeanUtils.instantiateClass(constructorToUse);
} else {
// Must generate CGLIB subclass.
// 生成 CGLIB 创建的子类对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
网友评论