Interview Blitz 78: What's the difference between @Autowired and @Resource?

Work together to create and grow together! This is the 12th day of my participation in the "Nuggets Daily New Plan·August Update Challenge", click to view the event details

Both @Autowired and @Resource are annotations used for dependency injection in Spring/Spring Boot projects. They both provide the ability to inject dependent objects into the current object, but there are many differences between the two, and this is also one of the common interview questions, so we will discuss it today. The difference between @Autowired and @Resource is mainly reflected in the following 5 points:

  1. different sources;
  2. The order of dependency lookup is different;
  3. Supported parameters are different;
  4. The usage of dependency injection is different;
  5. The compiler IDEA prompts differently.

1. Different sources

@Autowired and @Resource come from different "parent classes", where @Autowired is a Spring-defined annotation and @Resource is a Java-defined annotation from JSR-250 (Java 250 specification proposal).

Little knowledge: JSR is the abbreviation of Java Specification Requests, which means "Java Specification Proposal". Anyone can submit a JSR to the Java official, but only the finalized JSR will be released in the format of JSR-XXX, such as JSR-250, and the released JSR can be regarded as the specification or standard of the Java language.

2. Dependency search order is different

The function of dependency injection is to find the object in the Spring IoC container first, and then inject the object into the current class. There are two kinds of search implementations: search by name (byName) or search by type (byType), where @Autowired and @Resource both use name search and type search, but the order in which they are searched is different. Diametrically opposed.

2.1 @Autowired search order

@Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找,它的具体查找流程如下: image.png 关于以上流程,可以通过查看 Spring 源码中的 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 实现分析得出,源码执行流程如下图所示: image.png

2.2 @Resource 查找顺序

@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找,它的具体流程如下图所示: image.png 关于以上流程可以在 Spring 源码的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中分析得出。虽然 @Resource 是 JSR-250 定义的,但是由 Spring 提供了具体实现,它的源码实现如下: image.png

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 个参数,支持的参数如下图所示: image.png image.png

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 实现构造方法注入时就会提示以下错误: image.png

5.编译器提示不同

当使用 IDEA 专业版在编写依赖注入的代码时,如果注入的是 Mapper 对象,那么使用 @Autowired 编译器会提示报错信息,报错内容如下图所示: image.png 虽然 IDEA 会出现报错信息,但程序是可以正常执行的。 然后,我们再将依赖注入的注解更改为 @Resource 就不会出现报错信息了,具体实现如下: image.png

总结

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

  1. 来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250;
  2. 依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询;
  3. 支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数;
  4. The usage support of dependency injection is different: @Autowired supports both constructor injection, property injection and setter injection, while @Resource only supports property injection and setter injection;
  5. The compiler IDEA prompts differently: when injecting a Mapper object, the compiler will prompt an error with the @Autowired annotation, while the @Resource annotation will not prompt an error.

References & Acknowledgements

It is up to oneself to judge right and wrong, to listen to others, and to count the gains and losses.

Official Account: Analysis of Java Interview Questions

Interview Collection: gitee.com/mydb/interv…

Guess you like

Origin juejin.im/post/7137090639887335437
Recommended