所属规范
@Autowired:由Spring框架自己定义的注解,仅在Spring/Spring boot生态中生效,如果项目切换到其他依赖注入,该注解会失效
@Resource:JDK1.6+原生提供的注解,属于JSR-250JavaEE规范,是通用的依赖注入标准,只要框架兼容该规范,就能使用,跨框架兼容性更好
默认注入规则
默认注入规则有:类型优先和名称优先
类型优先:Spring会先在IOC容器中查找所有类型为指定类型的Bean
名称优先:Spring会先根据注解标注的字段名/方法名,查找IOC容器中同名的Bean
java
// 接口
public interface UserService{}
// 实现类1
@Service
public class UserServiceImpl1 implements UserService{}
// 实现类2
@Service
public class UserServiceImpl2 implements UserService{}
@Autowired:默认按类型注入
如果只有一个同类型Bean->直接注入,无需额外配置
如果有多个同类型的Bean->抛出NoUniqueBeanDefinitionException异常(类型匹配不唯一)
可以使用@Qualifier指定Bean名称
java
// 直接注入会报错(2个UserService类型Bean)
// @Autowired
// private UserService userService;
// 配合@Qualifier指定Bean名称,精准注入
@Autowired
@Qualifier("userServiceImpl1") // 对应Bean名称:userServiceImpl1
private UserService userService;
或用@Primary标记默认优先的Bean
java
@Service
@Primary // 标记为默认优先
public class UserServiceImpl1 implements UserService {}
// 此时直接注入不会报错,会自动注入UserServiceImpl1
@Autowired
private UserService userService;
@Resource:默认按照名称注入
找到同名Bean -> 直接注入,不管类型(只要类型兼容)
未找到同名Bean -> 降级为按类型匹配,此时行为和@Autowired一致(一个Bean注入,多个报错)
可以使用name/type属性,强制按名称/类型注入,无需其他注解
默认按字段名注入
java
// 报错:NoUniqueBeanDefinitionException(未找到同名Bean,类型匹配多个)
@Resource
private UserService userService;
手动指定name/type
java
// 直接指定Bean名称,精准注入userServiceImpl1
@Resource(name = "userServiceImpl1")
private UserService userService;
// 强制按类型注入,多个同类型仍会报错,行为与@Autowired一致
@Resource(type = UserService.class)
private UserService userService;
标注位置
@Autowired:可标注在字段、构造器、普通方法、方法参数上,Spring boot推荐构造器注入(能保证Bean初始化时依赖已注入,避免空指针)
java
// 构造器注入(推荐)
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
// 方法参数注入
public void setUserService(@Autowired UserService userService) {
this.userService = userService;
}
@Resource:Spring中仅支持标注在字段、setter方法上,不支持构造器、普通方法、方法参数
java
// 字段注入(支持)
@Resource
private UserService userService;
// setter方法注入(支持)
@Resource
public void setUserService(UserService userService) {
this.userService = userService;
}
// 构造器注入(不支持,Spring中无效果)
// @Resource
// public UserController(UserService userService) {
// this.userService = userService;
// }