首页 > 其他分享 >@Resource与@Autowired注解的区别

@Resource与@Autowired注解的区别

时间:2023-08-28 14:56:01浏览次数:38  
标签:byType Resource Autowired byName bean 匹配 UserService 注解

前言
1、什么是byName和byType
简单来说,byName就是根据变量名去匹配bean的id属性,而byType则是根据变量类型去匹配bean的class属性。实例说明:

<bean id="userService" class="com.test.UserServiceImpl"></bean>
@Autowired
private UserService userService;

此处byName就是拿变量名userService去匹配IOC容器的id为userService的bean,而byType就是拿变量类型UserService去匹配IOC容器的id为com.test.UserService.UserServiceImpl的bean,这里可以匹配成功是因为UserServiceImpl是UserService的实现类。

2、@Resource与@Autowired都是用来调用已经注入到IOC容器中的bean的。

一、@Resource
1、java中自带的注解 (javax.annotation.Resource)
2、默认按照名称(byName)方式进行bean装配,也可以按类型(byType)装配 
3、@Resource的作用范围:类、成员变量、方法
4、@Resource的使用
步骤:@Resource默认通过byName注入,如果没有匹配则通过byType注入。

@Service
public class UserServiceImpl1 implements UserService

@Service
public class UserServiceImpl2 implements UserService

@Resource
private UserService userService;

首先默认通过byName匹配,变量名userService无法匹配IOC容器中任何一个id(因为这里UserService有两个实现类,也就对应有相应的两个bean,即userServiceImpl1和userServiceImpl2),于是再通过byType匹配,发现类型UserService的实现类是两个,仍然无法确定,于是报错。
这时候就要提到@Resource两个重要的属性:name和type,它们用来显式指定byName和byType方式。
显示指定去匹配那个bean时,主要有以下四种情况:

// 1. 默认方式:byName 即不显示指定
@Resource
private UserService userDao;

// 2. 显示指定byName
@Resource(name="userService")
private UserService userService;

// 3. 显示指定byType
@Resource(type=UserService.class)
private UserService userService;

// 4. 显示指定byName和byType
@Resource(name="userService",type=UserService.class)
private UserService userService;

①既没指定name属性,也没指定type属性:默认通过byName方式注入,如果byName匹配失败,则使用byType方式注入(也就是上面的那个例子)
②指定name属性:通过byName方式注入,把变量名和IOC容器中的id去匹配,匹配失败则报错
③指定type属性:通过byType方式注入,在IOC容器中匹配对应的类型,如果匹配不到或者匹配到多个则失败报错
④同时指定name属性和type属性:在IOC容器中匹配,名字和类型同时匹配则成功,否则失败报错。

二、@Autowired
1、Spring自带的注解(org.springframework.beans.factory.annotation.Autowired)
2、默认按照类型(byType)方式进行bean装配,也可以按名称(byName)装配,需要结合@Qualifier如:@Autowired @Qualifier("manImpl")
3、默认要求装配的bean对象必须在IOC容器中存在,如果不存在会报错但不影响正常使用;若允许bean对象不存在,可设置@Autowired(required = false) 。即表示忽略当前要注入的bean,如果有直接注入,没有则跳过,也不会报错了
4、@Autowired的作用范围:成员变量、构造器、方法、参数、注解
5、@Autowired的使用
步骤:@Autowird默认的注入方式为byType,也就是根据类型匹配,当有多个实现时,则通过byName注入,也可以通过配合@Qualifier注解来显式指定name值,指明要使用哪个具体的实现类。

@Service
public class UserServiceImpl1 implements UserService

@Service
public class UserServiceImpl2 implements UserService

@Autowired
private UserService userService;

根据上面的步骤,可以很容易判断出,直接这么使用是会报错的。
原因:首先通过byType注入,判断UserService类型有两个实现,无法确定具体是哪一个,于是通过byName方式,这里的变量名userService也无法匹配IOC容器中id(此处指的userServiceImpl1和userServiceImpl2),于是报错。
(注意:通过注解注入到IOC容器的id值默认是其类名首字母小写,比如上面的UserServiceImpl1和UserServiceImpl2类bean的id默认为userServiceImpl1和userServiceImpl2)

解决方案:

// 方式一:改变变量名
//将原来的userservice改名为userServiceImpl1,这样就能匹配到对应的唯一bean了
@Autowired
private UserService userServiceImpl1;

// 方式二:配合@Qualifier注解来显式指定name值,这样就能匹配到对应的唯一bean了
@Autowired
@Qualifier(value = "userServiceImpl2")
private UserService userService;

// 方式三:配合@Primary注解来指定自动装配哪一个bean
//加上@Primary,匹配bean时,该bean就会被优先选中。
@Service
@Primary
public class UserServiceImpl1 implements UserService

三、总结
1、@Resource与@Autowired对比

 

2、@Autowired装配流程

 

3、@Resource装配流程

 

标签:byType,Resource,Autowired,byName,bean,匹配,UserService,注解
From: https://www.cnblogs.com/jiaodaoniujava/p/17662265.html

相关文章

  • 类型注解Callable
    fromcollections.abcimportCallable"""Callable[[ParamType1,ParamType2],ReturnType][参数1类型,参数2类型],返回值类型Callable[[],int]是Callable[[],float]的子类型,因为int是float的子类型。这意味着,那个Callable的返回值类型经历了协变(covariant),因为......
  • SpringBoot常用注解
    前段时间学习了SpringBoot这个快速开发框架,觉得这个框架写的真的是太优秀了,尤其是SpringBoot的自动配置机制,真的是过于强大,它使我们不再需要定义样板化的配置,大大提高了程序的开发效率。在这点上,我需要解释的是SpringBoot其实是对Spring和SpringMVC框架的再封装。那么,有的......
  • 为什么@Autowired写在属性上方进行依赖注入时,可以省略setter方法?
    众所周知,spring的依赖注入方式有两种,setter方法注入和构造器注入。但是在实际开发中,即便类的属性没有setter方法,类也没有构造器,只要在属性的上方添加@Autowired注解,这个类属性依然会被自动注入,那么到底是为什么呢?经过上网查询发现,spring其实是从容器查找符合属性类型的对象,通过......
  • 8、使用注解开发
    8、使用注解开发在Spring4之后,要使用注解开发,首先保证aop包被导入了使用注解要导入Context约束增加注解的支持Bean设置扫描某一个包下的注解<context:component-scanbase-package="com.an.pojo"></context:component-scan>属性如何注入在类上使用@Component注解来将......
  • 自定义注解实现日志打印
    首先什么是自定义注解?自定义注解是Java语言提供的一种机制,允许程序员定义自己的注解类型。注解是源代码级别的元数据,可以提供额外的信息给编译器、解析工具和运行时环境。下面是创建自定义注解的一般步骤:使用@interface关键字定义注解类型,注解类型名通常以@作为前缀,如@MyAnnotation......
  • 使用哪种注解处理后台Map参数类型,探究前端发送请求URL限制
    如何处理接口参数是Map类型探究URL限制法1:前端发送Get请求需求:为了得到分页结果,我将分页时需要的参数封装到Map中进行传递@GetMapping("/page")publicRqueryPage(@RequestParamMap<String,Object>params){}//1.测试GEThttp://localhost:8080/product/categorybrandrel......
  • Spring 常用注解
    今天给大家介绍一下Spring中的常用注解,同时这些注解也是Spring中经常用到的注解,下面我们就一起来看看都有哪些注解吧。1.@Controller在控制层使用,标识该类是SpringMVCcontroller处理器,用来创建处理http请求的对象。2.@Service在业务逻辑层使用,用于标注业务层组件。......
  • @NullSource 注解
    自动化测试过程中,需要验证某些特殊场景时,需要传空或者传nullnull参数的参数化注解 @NullSource 注解参数为空的参数化注解 @EmptySource 注解需要null和空都进行参数化,使用 @NullAndEmptySource 注解还有其他参数可以用@ValueSource继续提供importorg.junit.jup......
  • 超时处理@Timeout注解
    importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.junit.jupiter.api.Timeout;importstaticjava.lang.Thread.sleep;classTimeoutExampleTest{@Test@Timeout(7)voidtimeoutDemo1()throwsInterruptedExceptio......
  • @Value注解读取yml中的map/list配置
    读取map1、配置文件写法common:map:'{"username":"lisi","password":"123456"}'2、java代码的写法@Value("#{${common.map}}")privateMap<String,Object>map;读取list1、配置文件写法common:list:1,2,32、ja......