【springboot】你了解@Autowired 和 @Resource吗?@Autowired 和 @Resource深入分析
创始人
2024-04-05 22:55:31
0

@Autowired 和 @Resource深入分析

  • “认祖归宗”--@Autowired 和 @Resource来源
  • “通过现象看本质”--@Autowired 和 @Resource作用和区别
    • 1.现象一:一个业务接口只对应一个业务实现类
    • 2.现象二:一个业务接口 对应 两个或多个业务实现类

我们在开发中,一直用到的都是@Autowired,那么为什么这么用有没有想过?还有@Resource也可以作为注入的注解,为什么又不用?

“认祖归宗”–@Autowired 和 @Resource来源

那么首先,我们得知道这两个注解,他们是来自于哪?
@Autowired

package org.springframework.beans.factory.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {boolean required() default true;
}

我们可以看到,它是package org.springframework.beans.factory.annotation;是一个 spring 的注解 ;

@Resource

package javax.annotation;import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {

我们可以看到它是package javax.annotation;, 是一个J2EE (java自己)的注解。

总结

@Autowired 是一个 spring 的注解
@Resource 是一个J2EE (java自己)的注解

“通过现象看本质”–@Autowired 和 @Resource作用和区别

1.现象一:一个业务接口只对应一个业务实现类

UserService接口:

public interface User Service{public void test();
}

接口的实现类UserServiceImpl:

@Service
public class UserServieImpl implements UserService{
@Override
public void test()[System.out.print("test");
}

接下来我们给UserController里注入属性UserService
分别使用@Autorwired以及@Resource

...
@Autowired
private UserService userService;
...
...
@Resource
private UserService userService;
...

运行测试,结果都可以正常输出!

难道这么说它们两个随便用??

2.现象二:一个业务接口 对应 两个或多个业务实现类

我们加上一个UserServiceImpl2实现类:

@Service
public class UserServieImpl2 implements UserService{
@Override
public void test()[System.out.print("test");
}

现在,UserService接口有两个实现类,UserServiceImpl、UserServiceImpl2.

继续!!!

我们先使用@Autorwired注入!

...
@Autowired
private UserService userService;
...

运行结果!出错!

在这里插入图片描述

报错信息显示:

  1. 告诉我们 ,在MyTestController里面, 需要注入一个UserService (实现类), 但是却发现了两个这种类型的bean。

  2. 提供解决思路, 告诉我们可以使用@Primay注解 告诉哪一个是优先注入的,或者 使用@Qualifier 指定一下 需要注入哪个。

原因:

     @Autowired 是根据 类型 (byType)注入的 ,然后在找到type类型的bean时,如果发现有异常(不唯一等),会再去根据name去找bean注入。
    因为两个实现类bean都实现了UserService ,那肯定找到两个了,也就是有异常了,然后name我们写的是userService(实际两个业务实现类我们用@Service丢到spring容器里面默认名字是首字母小写userServiceImpl,userServiceImpl2),根本没有userService这个Bean。

异常处理

我们常配合 @Qualifier 注解去使用 ,指定一下 根据指定别名去注入。

@Service("userService")
public class UserServieImpl implements UserService{
@Override
public void test()[System.out.print("test");
}
...
@Autowired
@Qualifier("userService")
private UserService userService;
...

这样就可以解决 一个业务接口 对应 两个或多个业务实现类 的场景!!

总结

@Autowired 是根据 类型 (byType)注入的 , 然后当找到type类型的bean时,如果发现有异常(不唯一等),会再去根据name去找bean注入。


接下来,我们换成@Resource注解!

结果是:如同上面报错信息,也提示错误!

原因

@Resource 默认是 根据 名字(byName)注入的 。

而且 @Resource 其实提供了 name 和 type 属性值设置。
但是如果使用的时候,跟上文一样啥都没有指定,那么就是先byName 默认方式去找(userService):

  • 发现根本没有这个userService, 因为我们 注入到bean容器里面 是 这两个玩意(@Servcie):userServiceImpl、userServiceimpl2!

  • 而且咱们使用@Servcie 注入这俩玩意没有起别名,那么就是默认 首字母变小写 当做注入的bean名字。

  1. 那么 @Resource ,它根据可靠信息 name 名称 ( userService ),找不到bean;
  2. 那么就会根据 type 类型 (UserService) 去spring容器里面找找,有没有这种类型的bean;
    结果发现了 两个类型都是 UserService 的 两个倒霉孩子 userServiceImpl,userServiceImpl2 ;

所以就报错!!!

异常处理

@Resource 人家默认 byName 去找bean ,然后还提供name 和type 一起设置或者单一设置。
也就是说,这个@Resource 已经做得很到位了。

    简单解决,设置名字咯,刚刚说了 我们使用@Service 注入实现类bean的时候,没有特意指定名称,那么就是首字母小写当做了bean的名称,所以我们使用@Resource 也指定设置一下name:

...
@Resource(name = "userService")
private UserService userService;
...

这样一来,就解决了@Resource的这种bean冲突问题!

总结

@Resource 默认是根据 ByName注入的 , 然后如果发现有异常(不唯一等),会再去根据type去找bean注入。同时,提供了name、type两个属性可以进行指定name或者type

至此,这两个注解用法大家应该有所感受了吧!

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...