Spring 依赖注入方式
TIP
依赖注入(DI)是 IoC 的具体实现,Spring 通过多种方式将依赖注入到 Bean 中。
构造器注入(推荐)
java
@Component
public class UserService {
private final UserDao userDao;
private final RoleDao roleDao;
@Autowired
public UserService(UserDao userDao, RoleDao roleDao) {
this.userDao = userDao;
this.roleDao = roleDao;
}
}Setter 注入
java
@Component
public class UserService {
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}字段注入(简洁但不推荐)
java
@Component
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
}不同注入方式的对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| 构造器注入 | 不可变性、明确依赖、利于测试 | 构造器参数过多 |
| Setter 注入 | 可选依赖 | 可变性、依赖不明确 |
| 字段注入 | 代码简洁 | 无法构造不可变对象、依赖测试差 |
TIP
Spring 官方推荐使用构造器注入。当依赖过多时,说明类可能违反了单一职责原则,需要考虑拆分。
@Resource vs @Inject vs @Autowired
java
// @Autowired - Spring 注解,按类型装配
@Autowired
private UserDao userDao;
// @Resource - JSR-250,按名称装配
@Resource(name = "userDaoImpl")
private UserDao userDao;
// @Inject - JSR-330,按类型装配
@Inject
private UserDao userDao;@Qualifier 解决歧义
java
@Component
@Qualifier("primary")
public class PrimaryDataSource implements DataSource { }
@Component
@Qualifier("secondary")
public class SecondaryDataSource implements DataSource { }
@Autowired
@Qualifier("secondary")
private DataSource dataSource; // 明确指定使用 secondary