前言

编写代码中遇到一个问题,下面的代码一有时不会生效,必须通过代码二的方式,通过set方法注入DataSource然后再隐式转换赋值,所以稍微研究一下Autowired注解

1
2
3
4
5
6
7
8
9
//代码一
@Autowired
private DynamicRoutingDataSource dataSource;

//代码二
@Autowired
public void setDataSource(DataSource dataSource) {
this.dataSource = (DynamicRoutingDataSource) dataSource;
}

DynamicRoutingDataSource对象实例化的方法

1
2
3
4
5
6
7
8
9
10
11
@Bean
@ConditionalOnMissingBean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
dataSource.setPrimary(this.properties.getPrimary());
dataSource.setStrategy(this.properties.getStrategy());
dataSource.setProvider(dynamicDataSourceProvider);
dataSource.setP6spy(this.properties.getP6spy());
dataSource.setStrict(this.properties.getStrict());
return dataSource;
}

涉及相关类

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor的作用是在属性赋值时,进行一些额外的操作,它是Autowired注解发挥作用最根本的类,Spring创建Bean的过程中,在执行populateBean为对象变量赋值时,大部分地方都在调用InstantiationAwareBeanPostProcessor的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}

@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}

/** @deprecated */
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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 {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();

while(var4.hasNext()) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}

//pvs是判断是否有是否为当前Bean实例配置了property,xml中可以配置
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}

if (resolvedAutowireMode == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}

PropertyValues pvsToUse;
for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
//Autowired就是通过这里生效的
pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}

pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
}
}

if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}

this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}

if (pvs != null) {
//这里为Xml配置的实例变量或者配置了autowire的实例的变量赋值,需要注意Autowired注解不在这里赋值
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}

}
}

从populateBean代码可以看出,InstantiationAwareBeanPostProcessor对于populateBean方法相当重要。

关于popluate中调用autowireByName和autowireByType,这两个方法是根据相应的策略,为类中的set方法进行装配,如果是ByName,则根据set方法“set”后面的名称装配,如果是ByType,则根据方法内的参数类型进行装配,在这里还没有为变量赋值,只是先确定赋哪个值,可以通过xml配置或者@Bean注解的方式配置这两者,默认不启用

//以下情况将调用autowireByName装配

//<bean>设置autowire属性

<bean id="exampleBean" class="com.example.ExampleBean" autowire="byName">***</bean>

或

//@Bean注解使用autowire属性

@Bean(name = "exampleBean", autowire = Autowire.BY_NAME)

## AutowiredAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor,是实现Autowired注解逻辑的直接类,它实现的postProcessProperties方法会在类给属性赋值时,检查类对象使用到Autowired注解的变量或者方法,如果有,则尝试为对象变量赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//这一步是检查传入的类使用到Autowired注解的变量或者方法
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

try {
//这一步是为那些使用到Autowired注解的变量或者方法变量赋值
metadata.inject(bean, beanName, pvs);
return pvs;
} catch (BeanCreationException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
}
}

InjectionMetadata

这个类主要用于存储和管理与注解相关的元数据,这些元数据描述了如何以及在哪里应用自动注入。上述介绍的postProcessProperties方法中就用到了它。具体来说,InjectionMetadata会收集以下信息:

  • 注解的类型和属性。
  • 需要执行注入的目标成员(如字段或方法)。
  • 任何可能影响注入行为的特定配置(例如,是否需要强制要求依赖存在)。

AutowiredFieldElement

AutowiredFieldElement位于InjectionMetadata内部,它代表了注入点的一个基本元素,可以是一个需要进行依赖注入的字段、方法或是构造函数。这个类为处理各种类型的注入点提供了一个统一的基础抽象,封装了执行注入操作所需的基本逻辑和信息。AutowiredFieldElement有一个inject方法,它的子类通过实现这个方法完成不同的注入功能

AutowiredAnnotationBeanPostProcessor实现两个AutowiredFieldElement

  • AutowiredFieldElement:负责处理需要进行依赖注入的字段,例如直接在字段上使用@Autowired注解
  • AutowiredMethodElement:负责处理负责处理需要进行依赖注入的方法,例如直接在set方法上使用@Autowired注解

DefaultListableBeanFactory

DefaultListableBeanFactory提供了Bean定义的注册、Bean的创建、配置、管理和依赖注入等功能。是Spring框架中一个非常核心的类,它是Spring IoC容器的基础实现之一,负责管理和维护bean的定义(BeanDefinition)以及bean的实例化、配置和组装工作。这个类属于Spring的beans包下,是构建Spring应用上下文(ApplicationContext)的基石

doResolveDependency

doResolveDependency方法,它是Spring框架中bean依赖解析过程的一个核心步骤。这个方法主要用于解决和创建应用程序在运行时需要的bean之间的依赖关系。它是Spring IoC容器如何管理bean间复杂依赖关系背后的关键逻辑实现之一。根据步骤,它会解析依赖描述、查找候选bean、处理泛型依赖、创建或获取bean实例、处理特殊依赖类型、类型转换、处理可选依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);

Object var7;
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut == null) {
Class<?> type = descriptor.getDependencyType();
Object value = this.getAutowireCandidateResolver().getSuggestedValue(descriptor);
Object var23;
if (value != null) {
if (value instanceof String) {
String strVal = this.resolveEmbeddedValue((String)value);
BeanDefinition bd = beanName != null && this.containsBean(beanName) ? this.getMergedBeanDefinition(beanName) : null;
value = this.evaluateBeanDefinitionString(strVal, bd);
}

TypeConverter converter = typeConverter != null ? typeConverter : this.getTypeConverter();

try {
var23 = converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
return var23;
} catch (UnsupportedOperationException var18) {
Object var25 = descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter());
return var25;
}
}

Object multipleBeans = this.resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
var23 = multipleBeans;
return var23;
}

//这一步是查找候选者,即符合注入条件的对象,这一步返回的可能是Class对象也有可能是生成好的Bean
Map<String, Object> matchingBeans = this.findAutowireCandidates(beanName, type, descriptor);
String autowiredBeanName;
if (matchingBeans.isEmpty()) {
if (this.isRequired(descriptor)) {
this.raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}

autowiredBeanName = null;
return autowiredBeanName;
}

Object instanceCandidate;
Object result;
if (matchingBeans.size() > 1) {
autowiredBeanName = this.determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (!this.isRequired(descriptor) && this.indicatesMultipleBeans(type)) {
result = null;
return result;
}

result = descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
return result;
}

instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
Map.Entry<String, Object> entry = (Map.Entry)matchingBeans.entrySet().iterator().next();
autowiredBeanName = (String)entry.getKey();
instanceCandidate = entry.getValue();
}

if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}

if (instanceCandidate instanceof Class) {
//如果返回的是候选者Class对象,则在这一步尝试解析成候选者Bean,这一步其实就是调用beanFactory.getBean(autowiredBeanName)
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}

result = instanceCandidate;
if (instanceCandidate instanceof NullBean) {
if (this.isRequired(descriptor)) {
this.raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}

result = null;
}

if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}

Object var14 = result;
return var14;
}

var7 = shortcut;
} finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}

return var7;
}

这个方法比较重要的一步就是查找候选者,即上述代码中的

Map<String, Object> matchingBeans = this.findAutowireCandidates(beanName, type, descriptor);

这一步是查询候选者,返回的可能是生成好的Bean实例,也有可能是Bean的Class对象,

findAutowireCandidates

findAutowireCandidates 方法是Spring框架IoC(控制反转)容器中的一个重要组成部分。该方法负责在容器中寻找可以自动装配的bean候选者,这主要发生在依赖注入的过程中。它不仅会寻找bean候选者,还会尝试获取实例,它会尝试先获取候选者的名称,然后判断是否存在候选者的实例,如果存在,则返回候选者实例,如果不存在,则返回候选者的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
protected Map<String, Object> findAutowireCandidates(@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//这一步就是获取候选者们
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
Iterator var6 = this.resolvableDependencies.entrySet().iterator();

while(var6.hasNext()) {
Map.Entry<Class<?>, Object> classObjectEntry = (Map.Entry)var6.next();
Class<?> autowiringType = (Class)classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}

String[] var12 = candidateNames;
int var14 = candidateNames.length;

for(int var16 = 0; var16 < var14; ++var16) {
String candidate = var12[var16];
if (!this.isSelfReference(beanName, candidate) && this.isAutowireCandidate(candidate, descriptor)) {
//addCandidateEntry会尝试获取实例的方法
this.addCandidateEntry(result, candidate, descriptor, requiredType);
}
}

if (result.isEmpty()) {
boolean multiple = this.indicatesMultipleBeans(requiredType);
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
String[] var17 = candidateNames;
int var19 = candidateNames.length;

int var10;
String candidate;
for(var10 = 0; var10 < var19; ++var10) {
candidate = var17[var10];
if (!this.isSelfReference(beanName, candidate) && this.isAutowireCandidate(candidate, fallbackDescriptor) && (!multiple || this.getAutowireCandidateResolver().hasQualifier(descriptor))) {
this.addCandidateEntry(result, candidate, descriptor, requiredType);
}
}

if (result.isEmpty() && !multiple) {
var17 = candidateNames;
var19 = candidateNames.length;

for(var10 = 0; var10 < var19; ++var10) {
candidate = var17[var10];
if (this.isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && this.isAutowireCandidate(candidate, fallbackDescriptor)) {
this.addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}

return result;
}

这个方法当中

BeanFactoryUtils.beanNamesForTypeIncludingAncestors获取候选者名称

addCandidateEntry会尝试获取候选者实例或者类型

findAutowireCandidates方法后面涉及到一个比较重要的方法就是doGetBeanNamesForType,是实现获取候选者名称的关键之一

doGetBeanNamesForType

doGetBeanNamesForType是Spring IoC容器核心功能的一部分。这个方法主要用于根据给定的类型查找并返回所有匹配的bean名称列表。它是Spring在内部用于处理按类型查找Bean的请求的关键方法。它主要是通过遍历beanDefinitionNames(Spring Boot中所有Bean定义名称的集合,一般为类名或者类全限定名),然后判断是否和需要解析的Bean匹配,然后返回所有匹配的Bean名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList();
//获取所有Bean定义名称的集合的迭代器,用于遍历
Iterator var5 = this.beanDefinitionNames.iterator();

while(true) {
String beanName;
do {
if (!var5.hasNext()) {
var5 = this.manualSingletonNames.iterator();

while(var5.hasNext()) {
beanName = (String)var5.next();

try {
if (this.isFactoryBean(beanName)) {
if ((includeNonSingletons || this.isSingleton(beanName)) && this.isTypeMatch(beanName, type)) {
result.add(beanName);
continue;
}

beanName = "&" + beanName;
}

if (this.isTypeMatch(beanName, type)) {
result.add(beanName);
}
} catch (NoSuchBeanDefinitionException var13) {
this.logger.trace(LogMessage.format("Failed to check manually registered singleton with name '%s'", beanName), var13);
}
}

return StringUtils.toStringArray(result);
}

beanName = (String)var5.next();
} while(this.isAlias(beanName));

try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
if (!mbd.isAbstract() && (allowEagerInit || (mbd.hasBeanClass() || !mbd.isLazyInit() || this.isAllowEagerClassLoading()) && !this.requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = this.isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound = false;
boolean allowFactoryBeanInit = allowEagerInit || this.containsSingleton(beanName);
boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
if (!isFactoryBean) {
if (includeNonSingletons || this.isSingleton(beanName, mbd, dbd)) {
//判断当前Bean与目标Bean是否匹配
matchFound = this.isTypeMatch(beanName, type, allowFactoryBeanInit);
}
} else {
if (includeNonSingletons || isNonLazyDecorated || allowFactoryBeanInit && this.isSingleton(beanName, mbd, dbd)) {
matchFound = this.isTypeMatch(beanName, type, allowFactoryBeanInit);
}

if (!matchFound) {
beanName = "&" + beanName;
if (includeNonSingletons || this.isSingleton(beanName, mbd, dbd)) {
matchFound = this.isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
}

if (matchFound) {
result.add(beanName);
}
}
} catch (BeanDefinitionStoreException | CannotLoadBeanClassException var14) {
if (allowEagerInit) {
throw var14;
}

LogMessage message = var14 instanceof CannotLoadBeanClassException ? LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) : LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName);
this.logger.trace(message, var14);
this.onSuppressedException(var14);
} catch (NoSuchBeanDefinitionException var15) {
}
}
}

这个方法当中比较关键的就是通过isTypeMatch筛选符合条件的Bean的名称

isTypeMatch

isTypeMatch是Spring IoC容器内部用于检查和验证Bean类型是否匹配的核心方法之一。这个方法主要用于在实例化或注入Bean之前,确定一个已经注册的Bean(通过名字指定)是否与期望的类型相匹配。开头讲到通过方式一注入有时候行有时候不行,就是在这里找到了原因

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
String beanName = this.transformedBeanName(name);
boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);
Object beanInstance = this.getSingleton(beanName, false);
if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
if (beanInstance instanceof FactoryBean) {
if (isFactoryDereference) {
return typeToMatch.isInstance(beanInstance);
} else {
Class<?> type = this.getTypeForFactoryBean((FactoryBean)beanInstance);
return type != null && typeToMatch.isAssignableFrom(type);
}
} else {
if (!isFactoryDereference) {
if (typeToMatch.isInstance(beanInstance)) {
return true;
}

if (typeToMatch.hasGenerics() && this.containsBeanDefinition(beanName)) {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
Class<?> targetType = mbd.getTargetType();
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
Class<?> classToMatch = typeToMatch.resolve();
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
return false;
}

if (typeToMatch.isAssignableFrom(targetType)) {
return true;
}
}

ResolvableType resolvableType = mbd.targetType;
if (resolvableType == null) {
resolvableType = mbd.factoryMethodReturnType;
}

return resolvableType != null && typeToMatch.isAssignableFrom(resolvableType);
}
}

return false;
}
} else if (this.containsSingleton(beanName) && !this.containsBeanDefinition(beanName)) {
return false;
} else {
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
return parentBeanFactory.isTypeMatch(this.originalBeanName(name), typeToMatch);
} else {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
Class<?> classToMatch = typeToMatch.resolve();
if (classToMatch == null) {
classToMatch = FactoryBean.class;
}

Class<?>[] typesToMatch = FactoryBean.class == classToMatch ? new Class[]{classToMatch} : new Class[]{FactoryBean.class, classToMatch};
Class<?> predictedType = null;
if (!isFactoryDereference && dbd != null && this.isFactoryBean(beanName, mbd) && (!mbd.isLazyInit() || allowFactoryBeanInit)) {
RootBeanDefinition tbd = this.getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class<?> targetType = this.predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) {
predictedType = targetType;
}
}

if (predictedType == null) {
predictedType = this.predictBeanType(beanName, mbd, typesToMatch);
if (predictedType == null) {
return false;
}
}

ResolvableType beanType = null;
if (FactoryBean.class.isAssignableFrom(predictedType)) {
if (beanInstance == null && !isFactoryDereference) {
beanType = this.getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit);
predictedType = beanType.resolve();
if (predictedType == null) {
return false;
}
}
} else if (isFactoryDereference) {
predictedType = this.predictBeanType(beanName, mbd, FactoryBean.class);
if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) {
return false;
}
}

if (beanType == null) {
ResolvableType definedType = mbd.targetType;
if (definedType == null) {
definedType = mbd.factoryMethodReturnType;
}

if (definedType != null && definedType.resolve() == predictedType) {
beanType = definedType;
}
}

return beanType != null ? typeToMatch.isAssignableFrom(beanType) : typeToMatch.isAssignableFrom(predictedType);
}
}
}

直接用前言中的例子放到这个方法里面分析一下,方法开始会尝试根据待匹配的BeanName获取Bean实例,如果获取成功(这里指的获取成功,代表这之前,待匹配的BeanName已经实例化完成了),则判断待匹配的Bean实例是否是需要注入的对象的类或者子类,如果获取待匹配的BeanName的实例失败,则往后执行,普通的Bean最后都会通过判断待匹配的BeanName的Bean定义中的类是否是需要注入的对象的类或者子类。

这里我们假设DynamicRoutingDataSource已经实例化完成了,那么待匹配的Bean实例就是DynamicRoutingDataSource,而我们需要注入的也是DynamicRoutingDataSource类,那么这里就ok。这里的情况是因为引入JdbcTemplate之后,JdbcTemplate会引入DataSource,导致DynamicRoutingDataSource提前实例化了

如果这里DynamicRoutingDataSource还没有实例化完成,通过前言中DynamicRoutingDataSource实例化的方法可知,DynamicRoutingDataSource的Bean定义中的类是DataSource,而DataSource不是DynamicRoutingDataSource,更不是它的子类,很明显就无法匹配,最后也无法注入

而前言中的方式二可以成功是因为,哪怕DynamicRoutingDataSource还没有实例化完成,但是我们需要注入的类是DataSource,和DynamicRoutingDataSource的Bean定义中的DataSource类是一样的,所以可以注入成功

总结

出现这种情况,是因为,需要注入的对象和候选者对象比较的时候除了问题,候选者Bean是否已经实例化会影响比较的逻辑,这里又涉及到Bean实例化的时机,像本文中的例子,JdbcTemplate会先加载DataSource。

Spring Boot会先将程序中需要注册的类先放到一个定义集合,然后ApplicationContext就会循环定义集合创建Bean实例,在创建的过程中,遇到需要注入的情况,BeanFactory会直接创建需要注入的实例


本站总访问量:次本站总访问数:人
本站由 Peng Tong 使用 Stellar 1.29.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。