1. @Autowired 的依赖解析流程如何按类型匹配,多个候选 Bean 时怎样经 @Qualifier 与按名称回退确定最终注入对象
请说明 @Autowired 注解依赖注入的解析流程,它是如何先按类型匹配候选 Bean,当出现多个候选时又如何通过 @Qualifier 和按字段名回退来确定最终的注入对象?
- @Autowired 的 defaultRequired 与 byType 解析机制
- 多个候选时的 @Primary、@Qualifier、字段名回退三级优先级
- defaultAutowireCandidates 与候选查找的底层逻辑
@Autowired 采用的是 byType(按类型)解析。流程大致为:首先根据注入点的类型(字段类型或构造方法参数类型)调用 getBeanNamesForType 查找所有匹配的候选 Bean。若恰好只有一个候选,直接选它;若存在多个候选,Spring 会依次应用消歧规则:先通过 @Qualifier 指定的限定名(未标注时也可按 Bean 名称)过滤候选,在剩余候选中优先选择标记了 @Primary 的 Bean,最后才回退到"按字段名/参数名与 Bean 名称匹配"的规则。若这些规则仍无法唯一确定,且注入点是集合(List/Map)则全部注入;否则抛出 NoUniqueBeanDefinitionException。若一个候选都没有,且 required=true(默认),则抛出 NoSuchBeanDefinitionException。
这体现了 Spring 依赖注入的"单一候选优先、多候选逐级消歧"的设计哲学。@Primary 用于声明默认优先的 Bean,@Qualifier 提供显式限定,而按名称回退是最后兜底。理解这一顺序有助于排查 NoUniqueBeanDefinitionException 这类最常见的注入错误。
@Service
public class OrderService {
// 多候选时按名称回退:字段名 userServiceImpl 匹配 userServiceImpl 这个 Bean
@Autowired
private UserService userServiceImpl;
// 显式限定
@Autowired
@Qualifier("cacheUserService")
private UserService cacheUserService;
}