一个primary的都没有
@Lazy
true
是
处理普通的Bean
依赖注入MergedBeanDefinitionPostProcessor#postProcessProperties
@Qualifier注解指定的beanName
1. 是候选Bean@Bean(autowireCandidate = false)<bean autowire-candidate=\"false\"></bean>利用BeanPostProcessor操作BeanDefinition以上三种方式都可以间接改变当前Bean不是候选者,那么就不会满足条件。2. 参数泛型匹配3. 有@Qualifier注解4. 没有@Qualifier注解,但是BeanDefinition#defaultCandidate=true【spring6.2版本新增】((AbstractBeanDefinition)context.getBeanDefinition(\"\")).setDefaultCandidate(true);@Bean(defaultCandidate = false)以上两种方式都可以设置defaultCandidate的值。但默认都为true。
dependencyName = suggestedName那么就是用@Qualifier指定的名称作为依赖注入的名称
查找注入点MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
Map
指定依赖注入类型处理
只有一个默认的就返回那个
Optional
【spring6.2】版本新增没有@Fallback注解
返回优先级最高的,也就是值最小的
返回与@Qualifier相同的beanName
包装成AutowiredMethodElement
Set
返回相同的beanName
候选者中是否存在多个primary=true的Bean
返回dependencyName相同的beanName
返回Bean
只有一个符合条件的
带有@Autowired注解的方法 && 不是static修饰
【dependencyName】是否有对应的beanName存在containsBean(dependencyName)
存在
没有
单例池是否存在对象
多个primary
查找所有符合当前Class的BeanfindAutowireCandidates
依赖注入分为两个阶段第一个阶段:查找注入点查找注入点发生在,实例化Bean 之 添加三级缓存中间的一个过程。通过MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition回调实现注入点的查找。如何查找注入点的?AutowiredAnnotationBeanPostProcessor1. 循环所有属性。条件:但凡属性上有@Autowired、@Value其中一个注解就是注入点,并且属性不能是static修饰的。符合条件:将对应的Field、required属性都包装成AutowiredFieldElement对象,这里有个点需要注意,@Value没有required,默认也为required。2. 循环所有方法条件:但凡方法上有@Autowired、@Value其中一个注解就是注入点,并且方法不能是static修饰的,还要满足非封闭类,也就是Record修饰的类。符合条件之后:将当前方法对应的依赖描述器、Method、required包装成AutowiredMethodElement对象。缓存起来。查找完当前类之后,继续查找父类判断条件都是一样,一直查找父类,除非满足父类是Object就不查找依赖注入点了。然后将所有的注入点都缓存起来,等待Bean创建过程到依赖注入时就会从缓存获取所有需要注入的注入点,然后进行注入。第二个阶段:依赖注入依赖注入发生在实例化后 之 Aware回调之间。AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement【@Autowired】用于处理@Autowired属性依赖注入1. 创建DependencyDescriptor对象。 1.1、初始化参数名称发现器,在JDK8以上,可以通过反射获取方法参数的名称,在JDK8之前,需要使用本地变量表才能获取方法的参数的名称。2. 特殊注入类型的处理:Optional、ObjectFactory、jakarta.inject.Provider。3. @Lazy注解处理,若是属性上面还带有@Lazy注解时,不会直接查找依赖注入的Bean。而是直接创建一个代理对象返回。4. 真正开始查找依赖注入的Bean。 4.1、获取依赖注入的Class对象。 4.2、@Value注解处理【先跳过,后续再解析】。 4.3、获取依赖注入的name,若是是属性,那么就是属性名称,如果是方法,那么就是方法参数名称。 4.4、若是单例池、beanDefinitionMap中都不包括依赖注入的name。【第一次依赖注入的查找】 4.4.1、就会使用@Qualifier注解指定的value属性作为依赖注入的name。 4.4.2、若是没有指定@Qualifier又或者指定的@Qualifier对象value值不是一个beanName,那么第一次查找结束。 4.4.3、需要同时满足几个条件 需要依赖注入的Class是符合条件的 有@Qualifier 并且满足 BeanDefinition#defaultCandidate = false,但是通过@Component注解扫描出来的都是true。只有@Bean可以设置false。 @Component依赖注入的Bean没有添加@Fallback注解,或者通过@Bean没有添加@Fallback注解 不是自己注入自己 【满足以上条件开启】:就直接通过getBean方式创建Bean并且返回【第一次查找结束】。 4.5、解决容器类依赖注入的问题,也就是依赖注入的对象是Array、Collection、Set、List、Map。满足这些容器类型就会单独处理。【第二次依赖注入的查找】 4.6、不是容器类型那么就是普通对象类型的依赖注入【第三次依赖注入的查找】 4.6.1、若是没有对应的Bean,并且required=true。抛出异常。 4.6.2、有多个符合条件的Bean。 4.6.3、会经过以下步骤逐一筛选 【1】、primary 【2】、dependencyName 【3】、@Qualifier 【4】、@Priority 【5】、默认的候选者
生成代理对象返回
jakarta.inject.Provider
有可能只指定了@Qualifier注解,没有指定value属性
默认候选者
没有相同的
@Priority注解判断
创建Bean
创建BeangetBean(dependencyName)
抛出异常
方法查找
@Autowired注解查找AutowiredAnnotationBeanPostProcessor
@Value注解的处理
缓存
内置的BeanresolvableDependencies容器
是否容器类型
ObjectFactory
有多个默认的
数组
List
其他类型
包装成AutowiredFieldElement
【spring6.2】新增的
获取依赖注入的Class类型【type】
从@Qualifier注解中获取【suggestedName】
!isFallback(dependencyName)
属性查找
使用@Qualifier注解时是否指定了值
默认值为false。<bean primary=\"false\" ></bean>((AbstractBeanDefinition)context.getBeanDefinition(\"\")).setPrimary(true);可以通过设置@Primary注解和上面两种方式修改
一个符合条件的都没有并且required=true
也没有内置的Bean
多个符合条件的
Collection
获取依赖注入的名称【属性名/方法参数名】【dependencyName】
指定了
容器类型处理
带有@Autowired注解的属性 && 不是static修饰
【suggestedName】是否有对应的beanName存在
返回唯一的Primary的beanName
不存在
没有一个存在@Priority注解的Bean