乐趣区

关于springcloud:面试突击78Autowired-和-Resource-有什么区别

@Autowired 和 @Resource 都是 Spring/Spring Boot 我的项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到以后对象的性能,但二者却有泛滥不同,并且这也是常见的面试题之一,所以咱们明天就来盘它。
@Autowired 和 @Resource 的区别次要体现在以下 5 点:

  1. 起源不同;
  2. 依赖查找的程序不同;
  3. 反对的参数不同;
  4. 依赖注入的用法不同;
  5. 编译器 IDEA 的提醒不同。

1. 起源不同

@Autowired 和 @Resource 来自不同的“父类”,其中 @Autowired 是 Spring 定义的注解,而 @Resource 是 Java 定义的注解,它来自于 JSR-250(Java 250 标准提案)。

小常识:JSR 是 Java Specification Requests 的缩写,意思是“Java 标准提案”。任何人都能够提交 JSR 给 Java 官网,但只有最终确定的 JSR,才会以 JSR-XXX 的格局公布,如 JSR-250,而被公布的 JSR 就能够看作是 Java 语言的标准或规范。

2. 依赖查找程序不同

依赖注入的性能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到以后类中。而查找有分为两种实现:按名称(byName)查找或按类型(byType)查找,其中 @Autowired 和 @Resource 都是既应用了名称查找又应用了类型查找,但二者进行查找的程序却截然相同。

2.1 @Autowired 查找程序

@Autowired 是先依据类型(byType)查找,如果存在多个 Bean 再依据名称(byName)进行查找,它的具体查找流程如下:

对于以上流程,能够通过查看 Spring 源码中的 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 实现剖析得出,源码执行流程如下图所示:

2.2 @Resource 查找程序

@Resource 是先依据名称查找,如果(依据名称)查找不到,再依据类型进行查找,它的具体流程如下图所示:

对于以上流程能够在 Spring 源码的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中剖析得出。尽管 @Resource 是 JSR-250 定义的,然而由 Spring 提供了具体实现,它的源码实现如下:

2.3 查找程序小结

由下面的剖析能够得出:

  • @Autowired 先依据类型(byType)查找,如果存在多个(Bean)再依据名称(byName)进行查找;
  • @Resource 先依据名称(byName)查找,如果(依据名称)查找不到,再依据类型(byType)进行查找。

3. 反对的参数不同

@Autowired 和 @Resource 在应用时都能够设置参数,比方给 @Resource 注解设置 name 和 type 参数,实现代码如下:

@Resource(name = "userinfo", type = UserInfo.class)
private UserInfo user;

二者反对的参数以及参数的个数齐全不同,其中 @Autowired 只反对设置一个 required 的参数,而 @Resource 反对 7 个参数,反对的参数如下图所示:

4. 依赖注入的反对不同

@Autowired 和 @Resource 反对依赖注入的用法不同,常见依赖注入有以下 3 种实现:

  1. 属性注入
  2. 构造方法注入
  3. Setter 注入

这 3 种实现注入的实现代码如下。

a) 属性注入

@RestController
public class UserController {
    // 属性注入
    @Autowired
    private UserService userService;

    @RequestMapping("/add")
    public UserInfo add(String username, String password) {return userService.add(username, password);
    }
}

b) 构造方法注入

@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);
    }
}

c) 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 注入,当应用 @Resource 实现构造方法注入时就会提醒以下谬误:

5. 编译器提醒不同

当应用 IDEA 专业版在编写依赖注入的代码时,如果注入的是 Mapper 对象,那么应用 @Autowired 编译器会提醒报错信息,报错内容如下图所示:

尽管 IDEA 会呈现报错信息,但程序是能够失常执行的。
而后,咱们再 将依赖注入的注解更改为 @Resource 就不会呈现报错信息了,具体实现如下:

总结

@Autowired 和 @Resource 都是用来实现依赖注入的注解(在 Spring/Spring Boot 我的项目中),但二者却有着 5 点不同:

  1. 起源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250;
  2. 依赖查找的程序不同:@Autowired 先依据类型再依据名称查问,而 @Resource 先依据名称再依据类型查问;
  3. 反对的参数不同:@Autowired 只反对设置 1 个参数,而 @Resource 反对设置 7 个参数;
  4. 依赖注入的用法反对不同:@Autowired 既反对构造方法注入,又反对属性注入和 Setter 注入,而 @Resource 只反对属性注入和 Setter 注入;
  5. 编译器 IDEA 的提醒不同:当注入 Mapper 对象时,应用 @Autowired 注解编译器会提醒谬误,而应用 @Resource 注解则不会提醒谬误。

参考 & 鸣谢

  • www.cnblogs.com/felordcn/p/13063802.html
  • blog.csdn.net/CPLASF_/article/details/109225213

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java 面试真题解析

面试合集:https://gitee.com/mydb/interview

退出移动版