P63 Spring 面试必背:自动装配 + 注入方式 + 歧义解决全解析
面试题:Spring 自动装配是什么?有哪几种注入方式?多个同类 Bean 怎么解决歧义?
1. 什么是自动装配(Autowiring)
Spring 根据类型自动把依赖 Bean 注入到属性/构造器/方法上,不用手动 new:
java
@Autowired
private UserService userService;本质:按类型(byType)查找 Bean,找到就注入。
2. 三种注入方式
| 方式 | 写法 | 特点 |
|---|---|---|
| 字段注入 | @Autowired private X x; | 简单,但不利于测试、隐藏依赖(不推荐) |
| Setter 注入 | @Autowired public void setX(X x) | 可选依赖、可运行时替换,早期 XML 时代主流 |
| 构造器注入 | 构造器参数 + @Autowired(单构造器可省略) | Spring 官方推荐:不可变、依赖明确、易测试 |
java
@Service
public class OrderService {
private final UserService userService;
// 单个构造器时 Spring 自动注入,可省略 @Autowired
public OrderService(UserService userService) {
this.userService = userService;
}
}3. 装配规则与歧义解决
按类型 + 按名称
- 默认按类型找;只有一个匹配 Bean 直接注入;
- 有多个同类型 Bean 时,优先按字段名/参数名匹配(byName)。
解决歧义的三种方式
java
// ① @Qualifier 指定名称
@Autowired
@Qualifier("wechatPay")
private PayService payService;
// ② @Primary 指定首选
@Service
@Primary
public class WechatPayService implements PayService {}
// ③ 集合注入全部(Map/List)
@Autowired
private Map<String, PayService> payServices; // {beanName: instance}required 属性
java
@Autowired(required = false) // 找不到也不报错(可空)4. 高频追问
- @Autowired 和 @Resource 的区别:
@Autowired是 Spring 的,按类型注入;@Resource是 JSR-250 标准,先按名称、再按类型注入;
- @Autowired 注入的 Bean 是单例吗:默认是容器单例;
- 循环依赖:Spring 通过三级缓存解决 setter/字段注入的循环依赖,构造器注入无法解决(启动直接报错,这也是推荐构造器注入的原因之一)。
一句话总结
Spring 自动装配默认按类型查找 Bean,推荐构造器注入;多个同类 Bean 用 @Qualifier/@Primary/集合注入解决歧义;记住 @Autowired 按类型、@Resource 按名称优先,以及构造器注入天然规避循环依赖。