【2021-06-30】@Autowired 注解与 @Resource 注解有什么区别?
请移步至:
每日一题 查看更多的题目 ~
答:
首先,二者的相同点为:
@Autowired 与 @Resource 注解都可以用来装配 Bean;且,二者都可以写在字段上,也可以写在 setter 方法上。
二者的不同点:
@Autowired 注解是由 Spring 框架提供,而 @Resource 注解则是 javax.annotation.Resource 提供,也就是 J2EE 的标准,但是 Spring 支持该注解注入 Bean。
@Autowired 注解默认按照 Bean 类型(byType) 装配依赖的 Bean,默认的情况下,它要求依赖的对象必须存在,默认是不允许 null 值的,如果想要设置允许 null 值,可以设置它的 required 属性为 false。最常见的问题就是 IDEA 中, Mybatis 的 mapper 接口使用 @Autowired 引入会出现错误提示:
这种情况下,设置 required 属性为 false,即可解决问题
而 @Resource 注解默认按照 Bean 名字(byName)来装配依赖的 Bean。@Resource 有两个属性比较重要,分别是 name 与 type 。
@Resource 装配 Bean 的原则:- 如果没有指定 name 与 type 属性,即,默认情况按照 byName 进行装配
- 如果同时指定了 name 与 type 属性,则从 Spring 上下文中找到名称与类型都唯一匹配的 Bean 进行装配,找不到则抛出异常
- 如果仅指定了 name 属性,则从 Spring 上下文中查找名称匹配的 Bean 进行装配,找不到则抛出异常
- 如果仅指定了 type 属性,则从 Spring 上下文中查找类型匹配的,唯一的 Bean 进行装配,找不到或找到多个都会抛出异常
既然我们在上文中提到了 @Qualifier 注解,接下来就看下该注解的基本用法。
@Qualifier 注解限定哪个 Bean 应该被自动注入,该注解有助于消除歧义 Bean 的自动注入,举个例子:
MyService
public interface MyService{
// ...
}
MyServiceImpl1
@Service
public class MyServiceImpl1 implements MyService {
// ...
}
MyServiceImpl2
@Service
public class MyServiceImpl2 implements MyService {
// ...
}
当我们在 Controller 中将 MyService 服务注入进来时,因为有 MyService 的两个实现类,所以我们应该使用 @Qualifier 注解限定哪个实现类应该被注入:
@Controller
public class MyController {
@Autowired
@Qualifier("MyServiceImpl1") // 指定 MyServiceImpl1 应该被注入
private MyService myService;
// ...
}
@Qualifier 另一个常用的实践是可以让 @Autowired 注解按照 byName 来装配对象,示例如下:
public class Test {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
// ...
}