依赖注入
依赖注入(Dependency Injection,DI)是IoC的具体实现方式,容器自动将依赖对象注入到目标对象。
三种注入方式
构造器注入(推荐)
Java
@Service
public class OrderService {
private final UserService userService;
private final PaymentService paymentService;
// 构造器注入,依赖明确且不可变
@Autowired
public OrderService(UserService userService, PaymentService paymentService) {
this.userService = userService;
this.paymentService = paymentService;
}
}
Setter注入
Java
@Service
public class OrderService {
private UserService userService;
// Setter注入,适合可选依赖
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
字段注入(不推荐)
Java
@Service
public class OrderService {
@Autowired
private UserService userService; // 字段注入,依赖隐藏
}
注入方式对比
| 方式 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|
| 构造器注入 | 依赖明确、不可变、易测试 | 参数多时构造器冗长 | ⭐⭐⭐⭐⭐ |
| Setter注入 | 可选依赖、灵活 | 可能忘记注入、依赖可变 | ⭐⭐⭐ |
| 字段注入 | 代码简洁 | 难测试、依赖隐藏、反射性能差 | ⭐⭐ |
注解详解
@Autowired
Java
@Service
public class OrderService {
// 按类型注入
@Autowired
private UserService userService;
// 可选依赖
@Autowired(required = false)
private OptionalService optionalService;
// 构造器注入(Spring 4.3+ 单构造器可省略@Autowired)
public OrderService(UserService userService) {
this.userService = userService;
}
}
@Resource
Java
@Service
public class OrderService {
// 按名称注入
@Resource
private UserService userService;
// 指定Bean名称
@Resource(name = "primaryService")
private PaymentService paymentService;
}
@Autowired vs @Resource
| 特性 | @Autowired | @Resource |
|---|---|---|
| 来源 | Spring | JSR-250标准 |
| 默认匹配 | 按类型 | 指名称 |
| 指定名称 | @Qualifier | name属性 |
| 可选依赖 | required=false | 不支持 |
多候选Bean处理
@Qualifier
Java
@Service
public class OrderService {
@Autowired
@Qualifier("primaryPaymentService")
private PaymentService paymentService;
}
@Primary
Java
@Component
@Primary // 默认优先注入
public class PrimaryPaymentService implements PaymentService {
}
@Component
public class BackupPaymentService implements PaymentService {
}
集合注入
Java
@Service
public class OrderService {
// 注入所有同类型Bean
@Autowired
private List<PaymentStrategy> strategies;
// 注入Map,key为Bean名称
@Autowired
private Map<String, PaymentStrategy> strategyMap;
}
XML配置注入
XML
<bean id="orderService" class="com.example.OrderService">
<!-- 构造器注入 -->
<constructor-arg ref="userService"/>
<constructor-arg ref="paymentService"/>
<!-- Setter注入 -->
<property name="userService" ref="userService"/>
<property name="timeout" value="30"/>
</bean>
要点总结
- DI是IoC的具体实现,容器负责注入依赖
- 三种注入方式:构造器、Setter、字段
- 推荐构造器注入,依赖明确且便于测试
- @Autowired按类型,@Resource按名称
- 多候选Bean使用@Qualifier或@Primary指定
📝 发现内容有误?点击此处直接编辑