Spring依赖注入原理源码解析(spring依赖注入过程)

Spring依赖注入原理源码解析目录 一、寻找注入点
流程
源码
二、注入点注入
注入入口inject方法
字段注入
流程
源码
Set方法注入
流程
源码 核心方法doResolveDependency
流程
处理

目录

1.找到注入点

过程

源代码

2、注入点注入

注射方式

场注入

过程

源代码

设置方法注入

过程

源代码

核心方法doResolveDependency

过程

处理@value注释

过程

演示

处理@autowired注释

过程

演示

源代码

核心方法findAutowireCandidates

过程

源代码

一、寻找注入点

对于给定的bean生命周期,在实例化bean之后,Spring使用AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()来定位和缓存注入点。

流程

1.遍历当前类的所有属性字段

2. 检查字段中是否存在@Autowired、@Value 或@Inject。如果存在,将考虑该字段。

这是注入点

3. 如果场是静态的,则不执行注入。

4.使用@Autowired获取所需属性的值

5. 将字段信息构建到AutowiredFieldElement 对象中,并将其添加为注入点对象。

在currElements 集合中。

6. 遍历当前类的所有方法。

7. 判断当前方法是否为桥接方法,如果是,则查找原方法。

8. 检查方法中是否存在@Autowired、@Value、@Inject。如果存在,将考虑该方法。

这是注入点

9. 如果方法是静态的,则不执行注入。

10.使用@Autowired获取所需属性的值

11. 将方法信息构建到AutowiredMethodElement 对象中,并将其添加为注入点对象。

在currElements 集合中。

12、遍历完当前类的字段和方法后,再遍历父类,直到没有更多的父类为止。

13. 最后,将currElements 集合封装到InjectionMetadata 对象中,作为当前bean 的注入点集合。

对象并缓存。

源码

私有InjectionMetadata buildAutowiringMetadata(final Class? clazz) {

//如果bean 的类型是String.则根本不需要依赖注入

if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {

返回InjectionMetadata.EMPTY。

}

ListInjectionMetadata.InjectedElement 元素=new ArrayList();

类?目标类=clazz;

做{

最终ListInjectionMetadata.InjectedElement currElements=new ArrayList();

//遍历targetClass中的所有字段

ReflectionUtils.doWithLocalFields(targetClass, 字段- {

//@Autowired、@Value、@Inject 是否存在于字段中?

合并注释?

if (ann !=null) {

//static fields不是注入点,所以不会自动注入。

if (Modifier.isStatic(field.getModifiers())) {

如果(logger.isInfoEnabled()) {

logger.info(\’静态字段: 不支持自动连线注释\’ + field);

}

返回;

}

//构建注入点

需要布尔值=需要决策状态(ann);

currElements.add(new AutowiredFieldElement(字段,必填));

}

});

//遍历targetClass中的所有方法

ReflectionUtils.doWithLocalMethods(targetClass, 方法- {

方法BridgedMethod=BridgeMethodResolver.findBridgedMethod(方法);

if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(方法, BridgedMethod)) {

返回;

}

//方法中是否存在@Autowired、@Value、@Inject?

合并注释?

if (ann !=null method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {

//静态方法不是注入点,不会自动注入。

if (Modifier.isStatic(method.getModifiers())) {

如果(logger.isInfoEnabled()) {

logger.info(\’静态方法不支持自动连线注释: \’ + method);

}

返回;

}

//set方法最好有输入参数

if (method.getParameterCount()==0) {

如果(logger.isInfoEnabled()) {

logger.info(\’自动连线注释只能用于参数为: 的方法\’ +

方法);

}

}

需要布尔值=需要决策状态(ann);

PropertyDescriptor pd=BeanUtils.findPropertyForMethod(bridgedMethod, clazz);

currElements.add(new AutowiredMethodElement(方法,必需,pd));

}

});

elements.addAll(0, currElements);

targetClass=targetClass.getSuperclass();

}

while (targetClass !=null targetClass !=Object.class);

返回InjectionMetadata.forElements(elements, clazz);

}

二、注入点注入

在bean初始化之前,有一个步骤是在AutowiredAnnotationBeanPostProcessor的**postProcessProperties()**方法中填写属性,找到的注入点用@autowird、@进行标记。执行注入操作有两种方式,分别对应inject(target, beanName, pvs)方法的两个实现类,使用vaule和@inject注解或者set方法。自动连线字段元素

注入入口inject方法

字段注入

流程

1. 扫描所有AutowiredFieldElement 对象。

2. 将相应字段封装成DependencyDescriptor对象。

调用BeanFactory 的solveDependency() 方法,向其传递一个DependencyDescriptor 对象并依赖它。

使用搜索来查找与当前字段匹配的bean 对象。

4、将DependencyDescriptor对象和查找到的结果对象beanName封装为一。

例如,如果当前bean 是原型bean,则ShortcutDependencyDescriptor 对象将充当缓存。

当再次创建bean时,可以直接取出缓存的结果对象beanName,去BeanFactory中取出bean对象。

,无需再次搜索

5. 使用反射将结果对象分配给字段。

源码

@覆盖

protected voidject(Object Bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

字段字段=(字段) this.member;

对象的价值。

if (this.cached) {

//对于原型bean,第一次创建时,cached 为false。注入后,cached就会为true。

//第二次创建时,首先找到注入点,它是一个AutowiredFieldElement对象(此时缓存为真,所以在这里输入)。

//注入的具体bean对象不会在注入点缓存,但使用BeanName来确保注入不同的原型bean对象。

尝试{

值=solvedCachedArgument(beanName, this.cachedFieldValue);

}

catch (NoSuchBeanDefinitionException ex) {

//缓存参数的目标bean 被意外删除- 重新解析

值=solveFieldValue(字段, Bean, BeanName);

}

}

除此之外{

//根据字段从BeanFactory中找到匹配的bean对象

值=solveFieldValue(字段, Bean, BeanName);

}

//反射给字段赋值

如果(值!=null){

ReflectionUtils.makeAccessible(field);

field.set(Bean, 值);

}

}

Set方法注入

流程

1.遍历所有AutowiredMethodElement对象

2、遍历对应方法的参数,将每个参数封装成一个MethodParameter对象。

3. 将MethodParameter 对象封装为DependencyDescriptor 对象。

4. 调用BeanFactory 的solveDependency() 方法,向其传递一个DependencyDescriptor 对象并依赖它。

使用搜索来查找与当前方法的参数匹配的bean 对象。

5、将DependencyDescriptor对象和查找到的结果对象beanName封装为一。

例如,如果当前bean 是原型bean,则ShortcutDependencyDescriptor 对象将充当缓存。

当再次创建bean时,可以直接取出缓存的结果对象beanName,去BeanFactory中取出bean对象。

,无需再次搜索

6、利用反射将所有找到的结果对象传递给当前方法执行。

源码

@覆盖

protected voidject(Object Bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

//如果当前注入点值已存在于pvs 中,则跳过注入

if (checkPropertySkipping(pvs)) {

返回;

}

方法方法=(方法) this.member;

对象[]参数;

if (this.cached) {

尝试{

参数=solveCachedArguments(beanName);

}

catch (NoSuchBeanDefinitionException ex) {

//缓存参数的目标bean 被意外删除- 重新解析

参数=solveMethodArguments(方法, Bean, BeanName);

}

}

除此之外{

参数=solveMethodArguments(方法, Bean, BeanName);

}

if (参数!=null) {

尝试{

ReflectionUtils.makeAccessible(方法);

method.invoke(Bean, 参数);

}

catch (InvokingTargetException ex) {

抛出ex.getTargetException()。

}

}

}

核心方法doResolveDependency

无论注入点是属性还是set方法,最后都会构造依赖描述对象,并输入到doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)方法中,该方法需要检索那里的依赖bean对象。特定的属性或特定的setter 方法,requestingBeanName 表示已注入持续依赖项的bean。

流程

处理@value注解

流程

检查所需的类型是否是可选的,如果是,则封装它(立即)。不然就会下降。

检查所需的类型是否是ObjectFactory或ObjectProvider,如果是则封装(延迟),否则向下。

检查所需的类型(成员或参数)是否用@Lazy修饰,如果是则返回代理,否则返回。

解析@Value的值

如果你想要的值是字符串,先解析${ },然后解析#{ }

它不是字符串,因此您需要使用TypeConverter 对其进行转换

检查你想要的类型是流、数组、集合还是映射,如果不是,则向下。

检查BeanFactory 的resolvableDependency 是否注入了适当类型的对象。没有办法把它打下来。

在BeanFactory中查找类型匹配的bean并过滤父工厂。过滤时会考虑@Qualifier 和泛型。

结果计数为0,并引发NoSuchBeanDefinitionException 异常。

如果结果为1,则根据@Primary进行过滤。

如果结果仍然是1,则根据成员或变量名称进行过滤。

结果仍然是1,并且抛出NoUniqueBeanDefinitionException异常。

demo

包com.batch.a46;

导入org.springframework.beans.factory.annotation.Value。

导入org.springframework.beans.factory.config.BeanExpressionContext。

导入org.springframework.beans.factory.config.ConfigurableListableBeanFactory。

导入org.springframework.beans.factory.config.DependencyDescriptor。

导入org.springframework.beans.factory.support.DefaultListableBeanFactory。

导入org.springframework.context.annotation.AnnotationConfigApplicationContext。

导入org.springframework.context.annotation.Configuration。

导入org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver。

导入org.springframework.stereotype.Component。

导入java.lang.reflect.Field。

作品

@SuppressWarnings(\’全部\’)

公开课A46 {

公共静态无效主(字符串[] args)抛出异常{

AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(A46.class);

DefaultListableBeanFactory beanFactory=context.getDefaultListableBeanFactory();

ContextAnnotationAutowireCandidateResolver 解析器=new ContextAnnotationAutowireCandidateResolver();

solver.setBeanFactory(beanFactory);

//test1(上下文, 解析器, Bean1.class.getDeclaredField(\’home\’));

//test2(上下文, 解析器, Bean1.class.getDeclaredField(\’age\’));

//test3(上下文, 解析器, Bean2.class.getDeclaredField(\’bean3\’));

test3(上下文,解析器,Bean4.class.getDeclaredField(\’value\’));

}

私有静态无效test3(AnnotationConfigApplicationContext上下文,ContextAnnotationAutowireCandidateResolver解析器,字段){

依赖描述符dd1=新的依赖描述符(field, false);

//获取@Value的内容

字符串值=solver.getSuggestedValue(dd1).toString();

System.out.println(值);

//解析${}

值=context.getEnvironment().resolvePlaceholders(value);

System.out.println(值);

System.out.println(value.getClass());

//解析#{} @bean3

对象Bean3=context.getBeanFactory().getBeanExpressionResolver().evaluate(value, new BeanExpressionContext(context.getBeanFactory(), null));

//类型转换

对象结果=context.getBeanFactory().getTypeConverter().convertIfNecessary(bean3, dd1.getDependencyType());

System.out.println(结果);

}

私有静态无效test2(AnnotationConfigApplicationContext上下文,ContextAnnotationAutowireCandidateResolver解析器,字段){

依赖描述符dd1=新的依赖描述符(field, false);

//获取@Value的内容

字符串值=solver.getSuggestedValue(dd1).toString();

System.out.println(值);

//解开

析 ${}
value = context.getEnvironment().resolvePlaceholders(value);
System.out.println(value);
System.out.println(value.getClass());
Object age = context.getBeanFactory().getTypeConverter().convertIfNecessary(value, dd1.getDependencyType());
System.out.println(age.getClass());
}
private static void test1(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
DependencyDescriptor dd1 = new DependencyDescriptor(field, false);
// 获取 @Value 的内容
String value = resolver.getSuggestedValue(dd1).toString();
System.out.println(value);
// 解析 ${}
value = context.getEnvironment().resolvePlaceholders(value);
System.out.println(value);
}
public class Bean1 {
@Value(\”${JAVA_HOME}\”)
private String home;
@Value(\”18\”)
private int age;
}
public class Bean2 {
@Value(\”#{@bean3}\”) // SpringEL #{SpEL}
private Bean3 bean3;
}
@Component(\”bean3\”)
public class Bean3 {
}
static class Bean4 {
@Value(\”#{\’hello, \’ + \’${JAVA_HOME}\’}\”)
private String value;
}
}

处理@autowired注解
流程

@Autowired 本质上是根据成员变量或方法参数的类型进行装配
如果待装配类型是 Optional,需要根据 Optional 泛型找到 bean,再封装为 Optional 对象装配
如果待装配的类型是 ObjectFactory,需要根据 ObjectFactory 泛型创建 ObjectFactory 对象装配

此方法可以延迟 bean 的获取
如果待装配的成员变量或方法参数上用 @Lazy 标注,会创建代理对象装配

此方法可以延迟真实 bean 的获取
被装配的代理不作为 bean
如果待装配类型是数组,需要获取数组元素类型,根据此类型找到多个 bean 进行装配
如果待装配类型是 Collection 或其子接口,需要获取 Collection 泛型,根据此类型找到多个 bean
如果待装配类型是 ApplicationContext 等特殊类型

会在 BeanFactory 的 resolvableDependencies 成员按类型查找装配
resolvableDependencies 是 map 集合,key 是特殊类型,value 是其对应对象
不能直接根据 key 进行查找,而是用 isAssignableFrom 逐一尝试右边类型是否可以被赋值给左边的 key 类型
如果待装配类型有泛型参数

需要利用 ContextAnnotationAutowireCandidateResolver 按泛型参数类型筛选
如果待装配类型有 @Qualifier

需要利用 ContextAnnotationAutowireCandidateResolver 按注解提供的 bean 名称筛选
有 @Primary 标注的 @Component 或 @Bean 的处理
与成员变量名或方法参数名同名 bean 的处理

demo

package com.butch.a47;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Optional;
@Configuration
public class A47_1 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A47_1.class);
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
System.out.println(\”>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\”);
// 1. 根据成员变量的类型注入
DependencyDescriptor dd1 = new DependencyDescriptor(Bean1.class.getDeclaredField(\”bean2\”), false);
System.out.println(beanFactory.doResolveDependency(dd1, \”bean1\”, null, null));
System.out.println(\”>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\”);
// 2. 根据参数的类型注入
Method setBean2 = Bean1.class.getDeclaredMethod(\”setBean2\”, Bean2.class);
DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), false);
System.out.println(beanFactory.doResolveDependency(dd2, \”bean1\”, null, null));
System.out.println(\”>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\”);
// 3. 结果包装为 Optional<Bean2>
DependencyDescriptor dd3 = new DependencyDescriptor(Bean1.class.getDeclaredField(\”bean3\”), false);
if (dd3.getDependencyType() == Optional.class) {
dd3.increaseNestingLevel();
Object result = beanFactory.doResolveDependency(dd3, \”bean1\”, null, null);
System.out.println(Optional.ofNullable(result));
}
System.out.println(\”>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\”);
// 4. 结果包装为 ObjectProvider,ObjectFactory
DependencyDescriptor dd4 = new DependencyDescriptor(Bean1.class.getDeclaredField(\”bean4\”), false);
if (dd4.getDependencyType() == ObjectFactory.class) {
dd4.increaseNestingLevel();
ObjectFactory objectFactory = new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return beanFactory.doResolveDependency(dd4, \”bean1\”, null, null);
}
};
System.out.println(objectFactory.getObject());
}
System.out.println(\”>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\”);
// 5. 对 @Lazy 的处理
DependencyDescriptor dd5 = new DependencyDescriptor(Bean1.class.getDeclaredField(\”bean2\”), false);
ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
resolver.setBeanFactory(beanFactory);
Object proxy = resolver.getLazyResolutionProxyIfNecessary(dd5, \”bean1\”);
System.out.println(proxy);
System.out.println(proxy.getClass());
/*
1. Optional 及 ObjectFactory 对于内嵌类型的处理, 源码参考 ResolvableType
2. ObjectFactory 懒惰的思想
3. @Lazy 懒惰的思想
*/
}
static class Bean1 {
@Autowired @Lazy private Bean2 bean2;
@Autowired public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
@Autowired private Optional<Bean2> bean3;
@Autowired private ObjectFactory<Bean2> bean4;
}
@Component(\”bean2\”)
static class Bean2 {
/*@Override
public String toString() {
return super.toString();
}*/
}
}

源码

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
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);
// 解析Spring表达式(#{})
value = evaluateBeanDefinitionString(strVal, bd);
}
// 将value转化为descriptor所对应的类型
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()));
}
}
// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// required为true,抛异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary–>优先级最高—>name
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();
}
// 记录匹配过的beanName
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
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);
}
}

核心方法findAutowireCandidates

在处理完不同情况依赖bean,都需要组装对应的type,调用findAutowireCandidates方法,首先通过type获取需要依赖注入的bean

流程

1. 找出BeanFactory中类型为type的所有的Bean的名字,注意是名字,而不是Bean对象,因为我
们可以根据BeanDefinition就能判断和当前type是不是匹配,不用生成Bean对象
2. 把resolvableDependencies中key为type的对象找出来并添加到result中
3. 遍历根据type找出的beanName,判断当前beanName对应的Bean是不是能够被自动注入
4. 先判断beanName对应的BeanDefinition中的autowireCandidate属性,如果为false,表示不
能用来进行自动注入,如果为true则继续进行判断
5. 判断当前type是不是泛型,如果是泛型是会把容器中所有的beanName找出来的,如果是这种情
况,那么在这一步中就要获取到泛型的真正类型,然后进行匹配,如果当前beanName和当前泛
型对应的真实类型匹配,那么则继续判断
6. 如果当前DependencyDescriptor上存在@Qualifier注解,那么则要判断当前beanName上是否
定义了Qualifier,并且是否和当前DependencyDescriptor上的Qualifier相等,相等则匹配
7. 经过上述验证之后,当前beanName才能成为一个可注入的,添加到result中

源码

protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
// 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = 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;
}
}
}
for (String candidate : candidateNames) {
// 如果不是自己,则判断该candidate到底能不能用来进行自动注入
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 为空要么是真的没有匹配的,要么是匹配的自己
if (result.isEmpty()) {
// 需要匹配的类型是不是Map、数组之类的
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything…
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 匹配的是自己,被自己添加到result中
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass…
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
#以上关于Spring依赖注入原理源码解析的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92808.html

(0)
CSDN's avatarCSDN
上一篇 2024年7月4日 下午4:35
下一篇 2024年7月4日 下午4:35

相关推荐

  • 免费的SSL证书它不香吗?香,真香

    本文为远怀学堂原创,纯干货分享。SSL(Secure Sockets Layer)证书做网站开发、A

    2024年8月15日
    0
  • 戴尔PowerEdge R710

    戴尔PowerEdge R710是一款由戴尔公司开发的机架式服务器。中文名戴尔PowerEdge R710外文名DELL PowerEdge R710内存最高支

    2024年9月2日
    0
  • 编程语言中mod是什么

    编程语言中的MOD运算符是一种数学运算符,用于求两个数相除的余数。主要是编程,这个操作很基础也很重要,对于解决各种数学和逻辑问题至关重要。用一个简单的例子来说明,假设您需要确定一个…

    网站运维 2024年5月12日
    0
  • erp系统开发

    在当今数字化转型的浪潮中,企业对于高效、集成的管理系统的需求日益增长。ERP(企业资源规划)系统作为企业管理的核心工具,不仅能够帮助企业实现资源的优化配置,还能

    2024年9月25日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注