@Autowired 与@Resource的区别
@Autowired是Spring中的注解,@Resource是JSR-250中提供的注解
依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当前类中。而查找有分为两种实现:按名称(byName)查找或按类型(byType)查找,其中 @Autowired 和 @Resource 都是既使用了名称查找又使用了类型查找,但二者进行查找的顺序却截然相反。
@Autowired
@Autowired的依赖注入过程是由AutowiredAnnotationBeanPostProcessor支持的,具体的注入逻辑在DefaultListableBeanFactory#doResolveDependency
@Autowired的注入逻辑如下
@Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找,即找到所有类型符合的bean,如果没有类型符合的bean,则看@Autowired的required属性是否为true,是则抛出异常,否则返回null.
- 如果只有一个,则将这个bean注入
- 如果有多个bean,选择其中带有Primary注解的bean,如果只有一个直接注入,如果有多个bean带有Primary注解则报错,如果不存在就下一步
- 选择其中优先级最高的bean(优先级使用javax.annotation.Priority表明),如果只有一个直接注入,如果有多个bean的优先级并列最高则报错,如果不存在就下一步
- 选择beanName和当前要注入的属性名相同的bean进行注入,有则注入,没有则报错
@Resource
@Resource(name = "userinfo", type = UserInfo.class)
private UserInfo user;
@Resource的依赖注入过程是由CommonAnnotationBeanPostProcessor支持的具体的注入逻辑在CommonAnnotationBeanPostProcessor#autowireResource
@Resource的注入逻辑如下
1. 如果@Resource指定了name,则只会按照name进行查找,当找不到时抛出异常,找到将bean注入
2. 如果@Resource没有指定name,则把属性名作为名字进行查找,找到将bean注入,当按照名字查找不到时,按照类型进行查找
属性注入
@RestController
public class UserController {
// 属性注入
@Autowired
private UserService userService;
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
构造方法注入
@RestController
public class UserController {
// 构造方法注入
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
Setter 注入
@RestController
public class UserController {
// Setter 注入
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
注意:@Autowired 支持属性注入、构造方法注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入