Spring读源码系列05----bean的加载---中
- 循环依赖
- 什么是循环依赖
- spring是如何解决循环依赖的
- 1.构造器循环依赖
- 2.setter循环依赖
- 3.prototype范围的依赖处理
- 创建Bean
- AbstractAutowireCapableBeanFactory#createBean—创建bean前的准备
- AbstractAutowireCapableBeanFactory#doCreateBean—真正创建bean
- AbstractAutowireCapableBeanFactory#createBeanInstance--->创建bean的实例
- AbstractAutowireCapableBeanFactory#autowireConstructor--->使用解析得到的构造函数进行自动注入
- ConstructorResolver#autowireConstructor--->使用解析得到的构造函数进行自动注入
- AbstractAutowireCapableBeanFactory#instantiateBean--->使用默认构造函数进行实例化
- InstantiationStrategy#instantiate-->实例化策略
- SimpleInstantiationStrategy#instantiate-->简单实例化策略
- AbstractBeanFactory#initBeanWrapper----初始化BeanWrapper
- AbstractBeanFactory#getConversionService()----获取当容器关联的转换器服务组件
- AbstractBeanFactory#registerCustomEditors---注册自定义的属性编辑器
- AbstractAutowireCapableBeanFactory#doCreateBean--->DefaultSingletonBeanRegistry#addSingletonFactory--->在bean通过构造函数创建完毕,并进行相关autowire注入后,暴露出当前bean的单例工厂
- AbstractAutowireCapableBeanFactory#getEarlyBeanReference-->获取对指定 bean 的早期访问的引用,通常用于解析循环引用。
- AbstractAutowireCapableBeanFactory#populateBean—属性注入,xml解析的配置注入和后置处理器处理注解注入
- AbstractAutowireCapableBeanFactory#autowireByName
- AbstractAutowireCapableBeanFactory#autowireByType
-
- DefaultListableBeanFactory#resolveDependency----通过描述符号解析得到依赖的bean对象
- DefaultListableBeanFactory#doResolveDependency----通过描述符号解析得到依赖的bean对象
- AbstractAutowireCapableBeanFactory#applyPropertyValues---PropertyValues保存的属性注入到bean中
- AbstractAutowireCapableBeanFactory#convertForProperty---对传入的属性进行类型转换
- BeanWrapperImpi#convertForProperty---在没有覆盖默认TypeConvert的情况下,默认使用BeanWrapperImpi进行类型转换
- AbstractNestablePropertyAccessor#convertIfNecessary---真正进行类型转换
- AbstractAutowireCapableBeanFactory#createBeanInstance--->创建bean的实例
- AbstractAutowireCapableBeanFactory#doCreateBean—真正创建bean
- AbstractAutowireCapableBeanFactory#createBean—创建bean前的准备
本系列文章:
Spring读源码系列01—Spring核心类及关联性介绍
Spring读源码系列02----默认标签解析过程
Spring读源码系列03----自定义标签解析(待续中)
Spring读源码系列04----bean的加载—上
番外篇:
大家在阅读本篇文章到populateBean部分的时候,可以先看一下本篇文章,不然可能会有些懵逼
Spring读源码系列番外篇—01–PropertyValue相关类
循环依赖
什么是循环依赖
spring是如何解决循环依赖的
代码语言:javascript复制public class TestA {
private TestB testB;
public void a(){
testB.b();
}
public TestB getTestB() {
return testB;
}
public void setTestB(TestB testB) {
this.testB = testB;
}
}
代码语言:javascript复制public class TestB {
private TestC testC;
public void b() {
testC.c();
}
public TestC getTestC() {
return testC;
}
public void setTestC(TestC testC) {
this.testC = testC;
}
}
代码语言:javascript复制public class TestC {
private TestA testA;
public void c() {
testA.a();
}
public TestA getTestA() {
return testA;
}
public void setTestA(TestA testA) {
this.testA = testA;
}
}
Spring将循环依赖分为了三种情况:
1.构造器循环依赖
代码语言:javascript复制 <bean id="testA" class="org.deepSpring.TestA">
<constructor-arg index="0" ref="testB"/>
</bean>
<bean id="testB" class="org.deepSpring.TestB">
<constructor-arg index="0" ref="testC"/>
</bean>
<bean id="testC" class="org.deepSpring.TestC">
<constructor-arg index="0" ref="testA"/>
</bean>
代码语言:javascript复制 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
如果大家看过上集的话,应该知道是在getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法中:
代码语言:javascript复制beforeSingletonCreation(beanName); ---记录当前bean正在创建的状态
//这里矛头最终指向的是createBean方法
singletonObject = singletonFactory.getObject();----创建bean,发现依赖其他bean,递归创建,最终发现存在循环依赖
afterSingletonCreation(beanName);---清除当前bean正在创建的状态
注意:doGetBean方法中下面这行是xml配置文件中规定的depends-on属性,如果没写的话,就是null
代码语言:javascript复制//如果看过01xml配置文件解析的小伙伴应该清楚,当解析到bean标签中存在dependsOn属性的时候,会读取这些属性值,并设置进当前BeanDefinition中
String[] dependsOn = mbd.getDependsOn();
2.setter循环依赖
代码语言:javascript复制 /**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
单例工厂方法是在doCreateBean方法执行过程中暴露出来的,具体怎么做的,下面会进行分析
如果存在循环依赖,那么当TestC需要TestA进行注入的时候,会通过doGetBean方法来加载TestA,还记得我们在讲解doGetBean方法的时候说过,在一开始会尝试从singletonObjects和earlySingletonObjects中获取,如果都为空,那么再尝试从singletonFactories中获取
代码语言:javascript复制 // Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
如果忘记了getSingleton(String beanName, boolean allowEarlyReference)方法实现的小伙伴可以看一下
代码语言:javascript复制 @Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
3.prototype范围的依赖处理
doGetBean方法中获取prototype类型bean的时候,在一开始就会进行循环依赖的判断,如果存在就直接抛异常,不废话
代码语言:javascript复制 // Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
创建Bean
AbstractAutowireCapableBeanFactory#createBean—创建bean前的准备
这里衔接一下04末尾部分的内容:
代码语言:javascript复制 /**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" beanName "'");
}
//准备使用的BeanDefinition
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.
//解析出当前传入的BeanDefinition对应的Class对象---根据设置的class属性或者className来解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//验证及准备覆盖的方法----一会进行分析!!!
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.
//给BeanPostProcessors一个机会来返回代理真正的实例---第一次讲到是在FactoryBean的getObject方法调用过后
//!!!!重点分析
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 {
//真正创建bean的动作
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" beanName "'");
}
//返回创建后的bean实例
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);
}
}
AbstractAutowireCapableBeanFactory#doCreateBean—真正创建bean
代码语言:javascript复制 /**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//用来包装生成的bean
BeanWrapper instanceWrapper = null;
//如果需要实例化的bean是单例的
if (mbd.isSingleton()) {
//factoryBeanInstanceCache: 未完成 FactoryBean 实例的缓存:FactoryBean 名称到 BeanWrapper
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数注入和简单初始化
//!!!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//得到被BeanWrapper包装的bean对象
Object bean = instanceWrapper.getWrappedInstance();
//得到被BeanWrapper包装的bean的Class对象
Class<?> beanType = instanceWrapper.getWrappedClass();
//04篇在分析FactoryBean的getObject返回值的时候分析过,如果getObject返回null,那么最后返回的是一个NullBean
if (beanType != NullBean.class) {
//如果返回的不是NullBean类型,那么RootBeanDefinition会设置被当前bean被解析过的类型为beanType
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
//允许后处理器修改合并的 bean 定义。
synchronized (mbd.postProcessingLock) {
//postProcessed: MergedBeanDefinitionPostProcessor是否已经应用与当前beanDefintion上面
//如果是第一次的话,都是false,然后取反为真
if (!mbd.postProcessed) {
try {
//应用MergedBeanDefinitionPostProcessor后置处理器---autowired注解和Resource等注解相关的后置处理器
//就是在这里被应用的,我们后面详细分析!!!
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
//应用过后就会设置为true
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//是否允许早期曝光: 单例&&允许循环依赖&&当前bean正在创建中&&检测循环依赖
//前面说过:在getSingleton方法的beforeSingletonCreation(beanName)会记录当前bean正在创建的状态
//然后就是singletonFactory.getObject()--->createBean--->doCreatBean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
//如果允许早期曝光
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" beanName
"' to allow for resolving potential circular references");
}
//似不似非常地熟悉!!!
//getSiglenton方法一开始就会去单例缓存池和单例工厂缓存池里面尝试获取对应的单例bean
//为避免后期循环依赖,可以在bean初始化定义完成前将创建实例的ObjectFactory加入单例工厂集合
addSingletonFactory(beanName,
//这里第二个参数传入的是一个ObjectFactory参数类型,ObjectFactory前面说过是一个函数式接口
//getEarlyBeanReference方法下面进行分析!!!
//对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
//其中我们熟知的AOP就是在这里将advice动态注入bean中,若没有则直接返回bean,不做任何处理
//为什么要在此处进行aop的advice逻辑织入:
//在存在循环依赖的情况下,可以在此处确保提前暴露的bean也是被代理过的
//!!!
() -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//!!!
//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法---例如: init-method
//初始化给定的 bean 实例,应用工厂回调以及 init 方法和 bean 后处理器。
//对实现aware接口的bean进行处理
//applyBeanPostProcessorsBeforeInitialization
//invokeInitMethods
//applyBeanPostProcessorsAfterInitialization
//该方法也很重要!!!
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);
}
}
//如果当前bean允许早期暴露的话
if (earlySingletonExposure) {
//getSingleton(String beanName, boolean allowEarlyReference)方法doGetBean方法中也被调用过
//传入false表明只会尝试从singletonObjects和earlySingletonObjects去寻找bean,而不会去singletonFactories中寻找
Object earlySingletonReference = getSingleton(beanName, false);
//earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
//因为getSingleton(String beanName, boolean allowEarlyReference)方法中
//一上来会去singletonObjects和earlySingletonObjects去寻找bean,如果这两个地方没有
//再去singletonFactories中找,一般bean都是允许提前暴露的,因此这里都可以拿到对应的singletonFactory
//然后通过singletonFactory拿到对应的bean,但是上面讲过,这里的bean可能是被代理过的
//拿到bean后,就把当前singletonFactory移除,因为使用过了,并在earlySingletonObjects保存该bean
//现在大家在来思考一下: earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
//如果exposedObject==bean,说明exposedObject没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
//earlySingletonReference可能是被代理过的
exposedObject = earlySingletonReference;
}
//allowRawInjectionDespiteWrapping: 是否在循环引用的情况下注入原始 bean 实例,即使注入的 bean 最终被包装,默认为false
//hasDependentBean: 寻找当前bean是否依赖其他bean
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//得到依赖的bean集合
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//因为当前bean创建后依赖的bean一定是已经创建好的,actualDependentBeans不为空
//说明当前bean创建后其依赖的bean却没有创建完毕,也就是存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" beanName "' has been injected into other beans ["
StringUtils.collectionToCommaDelimitedString(actualDependentBeans)
"] in its raw version as part of a circular reference, but has eventually been "
"wrapped. This means that said other beans do not use the final version of the "
"bean. This is often the result of over-eager type matching - consider using "
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
//上面被圈出来的部分就是用来处理循环依赖的,如果没有循环依赖那么就会直接走到这里
// Register bean as disposable.
try {
//根据scope注册bean的Disposable方法!!!
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
AbstractAutowireCapableBeanFactory#createBeanInstance—>创建bean的实例
代码语言:javascript复制 /**
使用适当的实例化策略为指定的 bean 创建一个新实例:工厂方法、构造函数自动装配或简单实例化。
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//解析Class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//isNonPublicAccessAllowed默认返回true
//如果当前Class不是public修饰的并且默认也不允许反射创建非public的class,那么就会抛出异常
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());
}
//我们可以通过RootBeanDefinition中注册的回调来得到一个bean实例对象,然后被包装为BeanWrapper然后返回
//!!!
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果工厂方法不为空,则使用工厂方法初始化策略
//!!!
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
//传入的构造函数参数为空
if (args == null) {
//对于单例bean来说resolvedConstructorOrFactoryMethod 这个属性,在第一次解析完后,被赋值后,
//由于单例bean被缓存在了单例池中,下一次获取也不会重新加载了,自然不会再进入createBeanInstance方法了,也就没啥用了
//但是对于propotype类型的bean而言,他每一次获取都需要重新创建,因此为了防止每次都需要重新定位构造函数
//就有了这个属性resolvedConstructorOrFactoryMethod 来缓存已经被定位的构造函数了
synchronized (mbd.constructorArgumentLock) {
//一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前先需要根据参数所用构造函数和对应的工厂方法
//resolvedConstructorOrFactoryMethod:缓存解析好的构造函数方法和工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//propotype类型---这里不要总想着单例bean,不然你怎么都想不明白为啥这里要这样搞,因为你出发点错误了!
//将constructorArgumentsResolved: 构造函数参数标记为已解析
//constructorArgumentsResolved默认值为false,只有再第一次解析完成后,会被设置为true,
//那么下一次进来直接就可以精确定位了
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//propotype类型
//如果已经解析过,则使用解析好的构造函数方法不需要再次锁定
if (resolved) {
//autowireNecessary为真,说明构造函数参数已经被解析了
//为假,说明构造函数没有参数需要解析,是默认构造
if (autowireNecessary) {
//构造函数自动注入 !!!
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认的构造函数 !!!
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
//根据参数解析构造函数
//这里是通过后置处理器来处理的!!!
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数自动注入!!!
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
//默认构造的首选构造函数?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
//使用默认首选的构造函数进行自动注入
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
//使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
AbstractAutowireCapableBeanFactory#autowireConstructor—>使用解析得到的构造函数进行自动注入
代码语言:javascript复制 /**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param ctors the chosen candidate constructors ---->候选的构造函数,可能有很多个
* @param explicitArgs argument values passed in programmatically via the getBean method,
*/
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
//ConstructorResolver(this):为给定的工厂和实例化策略创建一个新的 ConstructorResolver,传入的是当前BeanFactory对象
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
spring3.0版本的时候,这个方法是一坨代码,现在被优化了,显得逻辑更加清晰,当然只是把之前放在该方法的逻辑都移动到了autowireConstructor中,—_____—
ConstructorResolver#autowireConstructor—>使用解析得到的构造函数进行自动注入
代码语言:javascript复制/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param chosenCtors chosen candidate constructors (or {@code null} if none)
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
//使用在该工厂注册的自定义编辑器初始化给定的 BeanWrapper。为将创建和填充 bean 实例的 BeanWrappers 调用。
//为当前BeanWrapper干了下面几件事:
//1.设置ConversionService--替代PropertyEditors
//2.registerCustomEditors---注册自定义的PropertyEditors
//关于属性转换这方面的东西,后面也会进行分析!!!
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//explicitArgs通过getBean方法传入
//如果getBean方法调用的时候指定了方法参数,那么直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//如果在getBean方法时候没有指定则尝试从配置文件中解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//先尝试从缓存中获取
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
//从缓存中找到了
//配置构造函数参数
//resolvedConstructorArguments: 用于缓存完全解析的构造函数参数的包可见字段。
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//preparedConstructorArguments: 用于缓存部分准备好的构造函数参数的包可见字段。
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果缓存中存在部分准备好的构造函数参数
if (argsToResolve != null) {
//解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
//缓存中的值可能是原始值也可能是最终值!!! --->后面如果有空会讲讲
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//上面都是尝试从缓存中拿到已经解析好的构造函数和构造参数
//没有被缓存
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
//拿到候选的构造函数数组
Constructor<?>[] candidates = chosenCtors;
//如果候选构造数组为空
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//isNonPublicAccessAllowed判断是获取所有构造,包括私有的,还是只获取public的构造函数
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);
}
}
//如果只有一个默认构造函数
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
//回顾上面的creatBeanInstance方法就会呼应起来,这里因为定位到的是默认构造
//因此会设置constructorArgumentsResolved构造函数已经被解析好的标识
//resolvedConstructorArguments解析好的构造参数为EMPTY_ARGS空参的构造参数
//resolvedConstructorOrFactoryMethod为解析好的构造函数
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
//通过instantiate来创建bean实例: 最终调用的是SimpleInstantiationStrategy的instantiate
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;
//explicitArgs不为NULL说明了getBean方法规定了调用的构造函数的参数类型
if (explicitArgs != null) {
//minNrOfArgs就是目标构造函数参数的数量
minNrOfArgs = explicitArgs.length;
}
//如果getBean没有传入构造函数参数数组
else {
//提取配置文件中的配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
//能解析到的参数个数
//!!!如果发现当前Bean的构造函数依赖其他bean,并且对应bean没有创建,那么会去递归创建依赖的bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//经过上面的分析可知minNrOfArgs就是目标构造函数参数的数量
//排序给定的构造函数,public构造函数优先参数数量降序,非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;
//遍历候选的构造函数数组
for (Constructor<?> candidate : candidates) {
//当前构造函数的参数个数
int parameterCount = candidate.getParameterCount();
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
//如果找到了可用的构造函数,或者需要的参数个数小于当前构造函数参数个数则终止,因为已经安装参数个数降序排列
break;
}
//参数个数不相等
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
//有参数则根据值构造对应参数类型的参数
try {
//ConstructorPropertiesChecker.evaluate解析ConstructorProperties注解
//ConstructorProperties注解是用来规定构造函数里面每个参数对应的名字
//@ConstructorProperties({"service1","hello1"}),在xml文件中要对应的配置为
//<bean id="newHello" class="com.lyk.service.NewHello">
// <constructor-arg name="hello1" value="hello"/>
// <constructor-arg name="service1" ref="helloService"/>
// </bean>
//!!!一会分析一下ConstructorPropertiesChecker.evaluate这个方法
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
//如果没有通过注解指定
if (paramNames == null) {
//获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取指定构造函数的参数名称----parameter.getName()
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 ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
//给定的显式参数 -> 参数长度必须完全匹配。
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//探索是否具有不确定行的构造函数存在,例如不同构造汉的参数为父子关系
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 on bean class [" mbd.getBeanClassName() "] "
"(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 on bean class [" mbd.getBeanClassName() "] "
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): "
ambiguousConstructors);
}
if (explicitArgs == null && argsHolderToUse != null) {
//将解析的构造函数加入缓存!!! --->一会看看干了啥子哦
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
//实例化后加入BeanWrapper中---instantiate!!!
//instantiate方法本质也是调用InstantiationStrategy strategy.instantiate()
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
AbstractAutowireCapableBeanFactory#instantiateBean—>使用默认构造函数进行实例化
代码语言:javascript复制 /**
* Instantiate the given bean using its default constructor.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return a BeanWrapper for the new instance
*/
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
InstantiationStrategy#instantiate–>实例化策略
SimpleInstantiationStrategy#instantiate–>简单实例化策略
代码语言:javascript复制 @Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//如果有需要覆盖或者动态替换的方法则需要使用CGLIB进行动态代理,因为可以在创建代理的同时将动态方法织入类中
if (!bd.hasMethodOverrides()) {
//走到该分支条件,说明不需要进行代理
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
//获取已经解析好的构造函数
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
//如果不存在--说明是无参构造
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
//如果是接口---抛出异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
//获取到无参构造
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
//将已经被解析的构造设置为无参构造
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//通过构造函数实例化bean !!!
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
//需要进行代理 !!! ---将lookup-method和replace-method相关替换方法逻辑织入进去
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
AbstractBeanFactory#initBeanWrapper----初始化BeanWrapper
无论是选取指定构造函数注入还创建实例还是通过无参构造实例化对象,都会在返回前需要去生成一个BeanWrapper包裹创建的实例对象返回
但是我们这里关注更多的是initBeanWrapper干了啥,如果不清楚BeanWrapper继承体系的小伙伴,建议先看一下下面的两篇文章:
Spring读源码系列番外篇08—BeanWrapper没有那么简单–上
Spring读源码系列番外篇08—BeanWrapper没有那么简单–中
使用在该工厂注册的自定义编辑器初始化给定的 BeanWrapper。
为将创建和填充 bean 实例的 BeanWrappers 调用。默认实现委托 registerCustomEditors。可以在子类中覆盖
代码语言:javascript复制protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(getConversionService());
//bw实现了PropertyEditorRegistry接口
registerCustomEditors(bw);
}
AbstractBeanFactory#getConversionService()----获取当容器关联的转换器服务组件
BeanWrapper的setConversionService()是来源于父接口ConfigurablePropertyAccessor,但是因为PropertyEditorRegistrySupport也有同名方法,所以真正调用的是PropertyEditorRegistrySupport中的方法实现
**AbstractBeanFactory内部维护了一个conversionService **
代码语言:javascript复制 @Override
public void setConversionService(@Nullable ConversionService conversionService) {
this.conversionService = conversionService;
}
@Override
@Nullable
public ConversionService getConversionService() {
return this.conversionService;
}
AbstractBeanFactory#registerCustomEditors—注册自定义的属性编辑器
AbstractBeanFactory维护了四个关于类型转换的属性
代码语言:javascript复制 /** Spring ConversionService to use instead of PropertyEditors. */
@Nullable
private ConversionService conversionService;
/** Custom PropertyEditorRegistrars to apply to the beans of this factory. */
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
/** Custom PropertyEditors to apply to the beans of this factory. */
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
/** A custom TypeConverter to use, overriding the default PropertyEditor mechanism. */
@Nullable
private TypeConverter typeConverter;
利用PropertyEditorRegistrar,我们可以向属性注册中心中注册自定义的属性编辑器,spring默认只提供了一个ResourceEditorRegistrar的实现类,感兴趣大家可以去看看,当前该类会在applicationContext初始化过程中被注册进去,后面会出文章进行讲解
代码语言:javascript复制public interface PropertyEditorRegistrar {
void registerCustomEditors(PropertyEditorRegistry registry);
}
registerCustomEditors可以把我们向容器中注册的属性编辑器
代码语言:javascript复制//使用已在此 BeanFactory 中注册的自定义编辑器初始化给定的 PropertyEditorRegistry。
//为将创建和填充 bean 实例的 BeanWrappers 以及用于构造函数参数和工厂方法类型转换的 SimpleTypeConverter 调用。
protected void registerCustomEditors(PropertyEditorRegistry registry) {
if (registry instanceof PropertyEditorRegistrySupport) {
//configValueEditorsActive设置为true
//激活仅用于配置目的的配置值编辑器,例如 StringArrayPropertyEditor。
((PropertyEditorRegistrySupport) registry).useConfigValueEditors();
}
//propertyEditorRegistrars是否有元素来注册自定义的属性编辑器
if (!this.propertyEditorRegistrars.isEmpty()) {
for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
try {
registrar.registerCustomEditors(registry);
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
if (logger.isDebugEnabled()) {
logger.debug("PropertyEditorRegistrar [" registrar.getClass().getName()
"] failed because it tried to obtain currently created bean '"
ex.getBeanName() "': " ex.getMessage());
}
onSuppressedException(ex);
continue;
}
}
throw ex;
}
}
}
//还要查看customEditors集合,然后去挨个注册
if (!this.customEditors.isEmpty()) {
this.customEditors.forEach((requiredType, editorClass) ->
registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
}
}
AbstractAutowireCapableBeanFactory#doCreateBean—>DefaultSingletonBeanRegistry#addSingletonFactory—>在bean通过构造函数创建完毕,并进行相关autowire注入后,暴露出当前bean的单例工厂
回顾doCreateBean方法中的这段代码:
代码语言:javascript复制 // Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//是否允许早期曝光: 单例&&允许循环依赖&&当前bean正在创建中&&检测循环依赖
//前面说过:在getSingleton方法的beforeSingletonCreation(beanName)会记录当前bean正在创建的状态
//然后就是singletonFactory.getObject()--->createBean--->doCreatBean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
//如果允许早期曝光
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" beanName
"' to allow for resolving potential circular references");
}
//似不似非常地熟悉!!!
//getSiglenton方法一开始就会去单例缓存池和单例工厂缓存池里面尝试获取对应的单例bean
//为避免后期循环依赖,可以在bean初始化定义完成前将创建实例的ObjectFactory加入单例工厂集合
addSingletonFactory(beanName,
//这里第二个参数传入的是一个ObjectFactory参数类型,ObjectFactory前面说过是一个函数式接口
//getEarlyBeanReference方法下面进行分析!!!
//对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
//其中我们熟知的AOP就是在这里将advice动态注入bean中,若没有则直接返回bean,不做任何处理
//为什么要在此处进行aop的advice逻辑织入:
//在存在循环依赖的情况下,可以在此处确保提前暴露的bean也是被代理过的
//!!!
() -> getEarlyBeanReference(beanName, mbd, bean));
}
代码语言:javascript复制 // Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" beanName
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
addSingletonFactory代码如下:
代码语言:javascript复制 protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
//前提是单例缓冲池中不能有该bean,不然说明该bean已经存在容器中了,提早曝光不是白瞎吗?
if (!this.singletonObjects.containsKey(beanName)) {
//bean的单例工厂加入singletonFactories集合
this.singletonFactories.put(beanName, singletonFactory);
//singletonFactories与earlySingletonObjects互斥
//我们在doGetBean方法一开始去缓存中寻找时,如果单例缓存池和早期单例缓存池中都没有找到
//那么会去获取该单例对象的单例工厂,然后利用该单例工厂获取到对应提早曝光的bean对象
//然后将该bean对象加入早期单例缓存池集合中,并将对应的单例工厂移除
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
AbstractAutowireCapableBeanFactory#getEarlyBeanReference–>获取对指定 bean 的早期访问的引用,通常用于解析循环引用。
代码语言:javascript复制 protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
//mbd.isSynthetic()--》true该bean是应用程序创建的,应用程序创建的bean不需要经过后置处理器处理
//!mbd.isSynthetic()-->true用户创建的bean需要经过后置处理器处理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
//应用后置处理器---aop逻辑在这里到底是如何织入的!!!---后面的系列再进行分析
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
AbstractAutowireCapableBeanFactory#populateBean—属性注入,xml解析的配置注入和后置处理器处理注解注入
代码语言:javascript复制/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
//BeanWrapper为NULL并且mdb没有属性需要填充
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
//翻译:
//让任何 InstantiationAwareBeanPostProcessors
//有机会在设置属性之前修改 bean 的状态。例如,这可以用于支持字段注入的样式。
//!mbd.isSynthetic()为true说明是用户定义的bean,需要被后置处理器进行处理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
//后置处理器返回值决定是否还需要继续填充bean
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
//获取mdb中bean 的属性值---PropertyValues封装了一堆PropertyValue
// 从Bean定义里面把准备好的值都拿出来~~~
// 它是个MutablePropertyValues,持有N多个属性的值~~~
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//获取mdb的自动注入模式
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
//只有自动注入模式为按照名字或者按照类型才会生效
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据名称自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
//!!!
autowireByName(beanName, mbd, bw, newPvs);
}
//根据类型自动注入
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
//!!!
autowireByType(beanName, mbd, bw, newPvs);
}
//MutablePropertyValues继承至PropertyValues
pvs = newPvs;
//newPvs得到的是最终需要注入的属性
}
//InstantiationAwareBeanPostProcessor是否已经初始化---存放该后置处理器的集合不为空即为初始化完毕
//上面都是xml配置解析出来后进行相关属性注入处理的过程----这类后置处理器处理的就是我们最常用的注解属性注入
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要依赖检查吗
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
//属性描述符号
PropertyDescriptor[] filteredPds = null;
//如果有相关后置处理器存在的话
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//这一步对我们来说更加重要一些
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
//对属性进行后置处理!!!---一些autowired注解,resource注解等相关后置处理器,会在这一步工作
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
//先尝试从缓存中获取当前BeanWrapper对应一组属性描述符号,如果缓存没有再去解析,然后放入缓存,防止下次还是需要使用
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//应用后置处理器!!!
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
//pvsToUse是通过后置处理器解析过属性上标注的注解后,得到最终需要赋值的属性集合
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//依赖检查,对应depends-on属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
//将属性应用到bean中---上面通过xml配置分析注入和后置处理器注解分析注入,得到了最终的一组属性集合
//下面就是把这组属性集合最终应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
AbstractAutowireCapableBeanFactory#autowireByName
代码语言:javascript复制 /**
* Fill in any missing property values with references to
* other beans in this factory if autowire is set to "byName".
* @param beanName the name of the bean we're wiring up.
* Useful for debugging messages; not used functionally.
* @param mbd bean definition to update through autowiring
* @param bw the BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
*/
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//寻找需要依赖注入的属性---而不是string字符串这种值类型
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//当前容器或者父容器中要有该类型bean
if (containsBean(propertyName)) {
//递归初始化相关bean!!!
//getBean再去掉用goGetBean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
//注册依赖
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" beanName
"' via property '" propertyName "' to bean named '" propertyName "'");
}
}
else {
//当前容器或者父容器中没有该类型bean
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" propertyName "' of bean '" beanName
"' by name: no matching bean found");
}
}
}
}
AbstractAutowireCapableBeanFactory#autowireByType
代码语言:javascript复制/**
* Abstract method defining "autowire by type" (bean properties by type) behavior.
* <p>This is like PicoContainer default, in which there must be exactly one bean
* of the property type in the bean factory. This makes bean factories simple to
* configure for small namespaces, but doesn't work as well as standard Spring
* behavior for bigger applications.
* @param beanName the name of the bean to autowire by type
* @param mbd the merged bean definition to update through autowiring
* @param bw the BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
*/
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
//寻找bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
//获取当前属性对应的属性描述符号
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
//探测指定属性的set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
//在实现优先级接口的后处理器的情况下,不允许使用 Eager init 进行类型匹配。
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
//获取依赖关系描述符
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,当属性存在多个封装bean时
//@Autowired private List<A> aList;将会找到所有匹配A类型的bean并将其注入--借助上面的DependencyDescriptor
//resolveDependency返回对应的依赖的bean!!!
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" beanName "' via property '"
propertyName "' to bean named '" autowiredBeanName "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
当前bean依赖哪些bean—>遍历获取每个bean的描述符—>根据描述符,通过resolveDependency得到对应的依赖bean
DefaultListableBeanFactory#resolveDependency----通过描述符号解析得到依赖的bean对象
代码语言:javascript复制 @Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//Optional类注入的特殊处理
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
//ObjectFactory类注入的特殊处理
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
//javaxInjectProviderClass类注入的特殊处理
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//通用处理逻辑
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
DefaultListableBeanFactory#doResolveDependency----通过描述符号解析得到依赖的bean对象
代码语言:javascript复制 @Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
//用于解析@Value注解
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
AbstractAutowireCapableBeanFactory#applyPropertyValues—PropertyValues保存的属性注入到bean中
代码语言:javascript复制/**
* Apply the given property values, resolving any runtime references
* to other beans in this bean factory. Must use deep copy, so we
* don't permanently modify this property.
*/
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
//说明没有属性需要进行注入
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
//如果mpvs中的包含的所有属性都已经被转换为对应的类型,那么可以直接设置到beanWrapper中
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
//直接调用beanWrapper的setPropertyValues将属性设置进去
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
//保存原始的属性集合
original = mpvs.getPropertyValueList();
}
else {
//如果psv并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
//这里从AbstractBeanFactory拿到TypeConverter
TypeConverter converter = getCustomTypeConverter();
//默认是不会设置的,如果设置了,说明用户使用自定义的类型转换器替换了默认的
if (converter == null) {
//因为BeanWrapperImpi实现了TypeConverter接口
converter = bw;
}
// 获取BeanDefinitionValueResolver,该Bean用于将bean定义对象中包含的值解析为应用于目标bean实例的实际值。
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
//这个集合时将转换好的属性放入该集合中
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
//遍历属性,将属性转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
//当前属性转换好了,就放入集合中
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
//拿到属性名和属性值
String propertyName = pv.getName();
Object originalValue = pv.getValue();
//INSTANCE: 自动装配标记值的规范实例。
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
//定位属性的set方法
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " pv);
}
//得到当前属性的描述符号
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
//根据描述符号解析得到对应的依赖值---该方法实现非常复杂
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 属性可写 并且 不是嵌套(如foo.bar,java中用getFoo().getBar()表示)或者索引(如person.addresses[0])属性
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// 用类型转换器进行转换
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
// 标记mpvs已经转换
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// 使用转换后的值进行填充~~~~~~~~~~
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
AbstractAutowireCapableBeanFactory#convertForProperty—对传入的属性进行类型转换
代码语言:javascript复制 /**
* Convert the given value for the specified target property.
*/
@Nullable
private Object convertForProperty(
@Nullable Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
// 需要特别注意的是:convertForProperty方法是BeanWrapperImpl的实例方法,并非接口方法
// 这个方法内部就用到了CachedIntrospectionResults,从何就和Java内省搭上了关系~~~
if (converter instanceof BeanWrapperImpl) {
return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
}
else {
// 自定义转换器---即我们调用setTypeConvert方法覆盖了默认的TypeConvert
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam);
}
}
BeanWrapperImpi#convertForProperty—在没有覆盖默认TypeConvert的情况下,默认使用BeanWrapperImpi进行类型转换
代码语言:javascript复制 @Nullable
public Object convertForProperty(@Nullable Object value, String propertyName) throws TypeMismatchException {
//缓存JavaBean的PropertyDescriptor描述信息的类
CachedIntrospectionResults cachedIntrospectionResults = getCachedIntrospectionResults();
//从缓存中获取当前属性对应的PropertyDescriptor
PropertyDescriptor pd = cachedIntrospectionResults.getPropertyDescriptor(propertyName);
if (pd == null) {
throw new InvalidPropertyException(getRootClass(), getNestedPath() propertyName,
"No property '" propertyName "' found");
}
//再拿到当前属性对应的类型描述符
TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd);
if (td == null) {
td = cachedIntrospectionResults.addTypeDescriptor(pd, new TypeDescriptor(property(pd)));
}
//进行类型转换
return convertForProperty(propertyName, null, value, td);
}
调用的是下面这个重载方法
代码语言:javascript复制 @Nullable
protected Object convertForProperty(
String propertyName, @Nullable Object oldValue, @Nullable Object newValue, TypeDescriptor td)
throws TypeMismatchException {
//属性名 旧值(上面没传) 新值(要进行转换的值) 当前属性对应的class类型 当前属性的类型描述符号
return convertIfNecessary(propertyName, oldValue, newValue, td.getType(), td);
}
AbstractNestablePropertyAccessor#convertIfNecessary—真正进行类型转换
convertIfNecessary最终调用到AbstractNestablePropertyAccessor而非TypeConverterSupport的convertIfNecessary方法,
但是typeConverterDelegate还是用的TypeConverterSupport的
代码语言:javascript复制 @Nullable
private Object convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue,
@Nullable Object newValue, @Nullable Class<?> requiredType, @Nullable TypeDescriptor td)
throws TypeMismatchException {
Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate");
try {
//调用类型转换委托类完成类型转换
return this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, requiredType, td);
}
catch (ConverterNotFoundException | IllegalStateException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(getRootInstance(), this.nestedPath propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, requiredType, ex);
}
catch (ConversionException | IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(getRootInstance(), this.nestedPath propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, requiredType, ex);
}
}
最终调用到的是typeConverterDelegate完成类型转换,该类具体源码不再贴出,感兴趣的小伙伴可以阅读下面这篇文章来了解具体实现:
Spring读源码系列番外篇08—BeanWrapper没有那么简单–上