@Autowired 注解与 @Resource 注解有什么区别?

439 阅读2分钟

请移步至 【DobbyKim 的每日一题】 查看更多的题目~

答:

首先,二者的相同点为:

@Autowired 与 @Resource 注解都可以用来装配 Bean;且,二者都可以写在字段上,也可以写在 setter 方法上。

二者的不同点:

  1. @Autowired 注解是由 Spring 框架提供,而 @Resource 注解则是 javax.annotation.Resource 提供,也就是 J2EE 的标准,但是 Spring 支持该注解注入 Bean。

  2. @Autowired 注解默认按照 Bean 类型(byType) 装配依赖的 Bean,默认的情况下,它要求依赖的对象必须存在,默认是不允许 null 值的,如果想要设置允许 null 值,可以设置它的 required 属性为 false。最常见的问题就是 IDEA 中, Mybatis 的 mapper 接口使用 @Autowired 引入会出现错误提示:

    @Autowired 注解与 @Resource 注解有什么区别? 这种情况下,设置 required 属性为 false,即可解决问题

    @Autowired 注解与 @Resource 注解有什么区别? 而 @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;
	// ...
}