目录
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