
假设存在以下基础类(用于注入场景):
// 接口
public interface UserDao {
void query();
}
// 实现类1
@Repository("userDaoMysql") // 指定Bean名称为userDaoMysql
public class UserDaoMysql implements UserDao {
@Override
public void query() {
System.out.println("Mysql查询用户");
}
}
// 实现类2
@Repository("userDaoOracle") // 指定Bean名称为userDaoOracle
public class UserDaoOracle implements UserDao {
@Override
public void query() {
System.out.println("Oracle查询用户");
}
}支持字段注入、构造器注入、setter 注入,需搭配@Qualifier指定名称(当同类型 Bean 多个时)。
@Service
public class UserService {
// 同类型Bean多个,必须用@Qualifier指定名称,否则报错
@Autowired
@Qualifier("userDaoMysql");
private UserDao userDao;
public void getUsers() {
userDao.query(); // 输出:Mysql查询用户
}
}@Service
public class UserService {
private UserDao userDao;
// 构造器注入,同类型多个时加@Qualifier
@Autowired
public UserService(@Qualifier("userDaoOracle") UserDao userDao) {
this.userDao = userDao;
}
public void getUsers() {
userDao.query(); // 输出:Oracle查询用户
}
}@Service
public class UserService {
private UserDao userDao;
@Autowired
@Qualifier("userDaoMysql")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUsers() {
userDao.query(); // 输出:Mysql查询用户
}
}@Service
public class UserService {
// 若容器中无UserDao类型Bean,不会报错(userDao为null)
@Autowired(required = false)
private UserDao userDao;
}仅支持字段注入和 setter 注入,可通过name或type属性指定匹配规则。
@Service
public class UserService {
// 字段名=Bean名称(userDaoMysql),直接匹配
@Resource
private UserDao userDaoMysql;
public void getUsers() {
userDaoMysql.query(); // 输出:Mysql查询用户
}
}@Service
public class UserService {
// 明确指定Bean名称,与字段名无关
@Resource(name = "userDaoOracle")
private UserDao userDao;
public void getUsers() {
userDao.query(); // 输出:Oracle查询用户
}
}@Service
public class UserService {
// 按类型匹配,若存在多个UserDao实现类则报错
@Resource(type = UserDaoMysql.class)
private UserDao userDao;
public void getUsers() {
userDao.query(); // 输出:Mysql查询用户
}
}@Service
public class UserService {
// 仅注入名称为userDaoOracle、类型为UserDaoOracle的Bean
@Resource(name = "userDaoOracle", type = UserDaoOracle.class)
private UserDao userDao;
}对比维度 | @Autowired | @Resource |
|---|---|---|
来源 | Spring 框架注解 | JDK 标准注解(Java EE) |
默认装配规则 | 按类型(Type)匹配 | 先按名称(Name),再按类型 |
支持的属性 | 仅required(控制是否必须注入) | name、type、lookup等 |
注入方式支持 | 字段、构造器、setter 注入 | 仅字段、setter 注入 |
跨框架兼容性 | 依赖 Spring,非 Spring 环境不可用 | 通用,支持 Spring、JPA 等多种框架 |
同类型多 Bean 处理 | 需搭配@Qualifier指定名称 | 直接通过name属性指定 |
异常处理 | 无匹配Bean时抛NoSuchBeanDefinitionException | 名称不匹配时抛NoSuchBeanDefinitionException |
处理器 | AutowiredAnnotationBeanPostProcessor | CommonAnnotationBeanPostProcessor |
@Autowired(required = false))。required属性可灵活控制 Bean 是否必须存在;@Qualifier,代码稍繁琐。name属性指定 Bean,无需搭配其他注解;lookup实现方法注入)。required的属性,若注入失败直接抛出异常;name属性,拼写错误易导致注入失败。注解 | 优点 | 缺点 |
|---|---|---|
@Autowired | 深度集成Spring,支持构造器/方法注入 | 强依赖Spring,灵活性较低 |
@Resource | 跨环境兼容性强,按名称注入更明确 | 功能单一,不支持required属性配置 |
@Autowired(推荐构造器注入 +@Qualifier),享受 Spring 生态优势;@Resource,保证兼容性和标准性;@Resource(name="xxx"),按类型装配用@Autowired(单 Bean)或@Autowired+@Qualifier(多 Bean)。