Entrevista Blitz 78: ¿Cuál es la diferencia entre @Autowired y @Resource?

¡Trabajar juntos para crear y crecer juntos! Este es el día 12 de mi participación en el "Nuevo plan diario de los Nuggets·Desafío de actualización de agosto", haga clic para ver los detalles del evento

Tanto @Autowired como @Resource son anotaciones que se utilizan para la inserción de dependencias en proyectos Spring/Spring Boot. Ambos brindan la capacidad de inyectar objetos dependientes en el objeto actual, pero hay muchas diferencias entre los dos, y esta también es una de las preguntas comunes de la entrevista, por lo que la discutiremos hoy. La diferencia entre @Autowired y @Resource se refleja principalmente en los siguientes 5 puntos:

  1. diferentes fuentes;
  2. El orden de búsqueda de dependencia es diferente;
  3. Los parámetros admitidos son diferentes;
  4. El uso de la inyección de dependencia es diferente;
  5. El compilador IDEA solicita de manera diferente.

1. Diferentes fuentes

@Autowired y @Resource provienen de diferentes "clases principales", donde @Autowired es una anotación definida por Spring y @Resource es una anotación definida por Java, que proviene de JSR-250 (propuesta de especificación Java 250).

Poco conocimiento: JSR es la abreviatura de Solicitudes de especificación de Java, que significa "Propuesta de especificación de Java". Cualquiera puede enviar un JSR al oficial de Java, pero solo el JSR finalizado se publicará en el formato de JSR-XXX, como JSR-250, y el JSR publicado se puede considerar como la especificación o estándar del lenguaje Java.

2. El orden de búsqueda de dependencia es diferente

La función de la inyección de dependencia es encontrar primero el objeto en el contenedor Spring IoC y luego inyectar el objeto en la clase actual. Hay dos implementaciones de búsqueda: búsqueda por nombre (byName) o búsqueda por tipo (byType), donde tanto @Autowired como @Resource usan búsqueda por nombre y búsqueda por tipo, pero el orden de búsqueda es diferente.

2.1 Orden de búsqueda de @Autowired

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

2.2 @Resource 查找顺序

@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找,它的具体流程如下图所示: imagen.png 关于以上流程可以在 Spring 源码的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中分析得出。虽然 @Resource 是 JSR-250 定义的,但是由 Spring 提供了具体实现,它的源码实现如下: imagen.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 个参数,支持的参数如下图所示: imagen.png imagen.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 实现构造方法注入时就会提示以下错误: imagen.png

5.编译器提示不同

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

总结

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

  1. 来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250;
  2. 依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询;
  3. 支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数;
  4. El soporte de uso de la inyección de dependencia es diferente: @Autowired admite la inyección de constructor, la inyección de propiedad y la inyección de Setter, mientras que @Resource solo admite la inyección de propiedad y la inyección de Setter;
  5. El compilador IDEA solicita de manera diferente: al inyectar un objeto Mapper, el compilador generará un error con la anotación @Autowired, mientras que la anotación @Resource no generará un error.

Referencias y reconocimientos

Depende de uno mismo juzgar el bien y el mal, escuchar a los demás y contar las ganancias y las pérdidas.

Cuenta oficial: análisis de las preguntas de la entrevista de Java

Colección de entrevistas: gitee.com/mydb/interv…

Supongo que te gusta

Origin juejin.im/post/7137090639887335437
Recomendado
Clasificación