@AutoWired与@Resource

news2024/12/28 5:31:02

参考 :

@Qualifier - 搜索结果 - 知乎

@Autowired和@Resource的区别是什么? - 知乎

面试突击78:@Autowired 和 @Resource 有什么区别? - 掘金

目录

同一类型多个@Bean报错问题

@Resource注解

@Resource的查找顺序

@Resource注解实现依赖注入

@Resource的来源

@Resource的方法参数

@Resource注解的应用范围

@AutoWired

@AutoWired查找顺序

@AutoWired依赖注入方式

@AutoWired来源

@AutoWired方法参数

@AutoWired注解作用范围

@AutoWired与@Resource的区别

@Qualifier

@primary

解决同一类型Bean报错的问题

使用Resource注解解决

使用@AutoWired注解 + @Qualifier注解解决

使用@primary注解解决


我们通过一个小栗子/一个问题,引出@AutoWired注解和@Resource注解还有@Qualifier注解,利用注解解决这个问题,然后在讲解@AutoWired注解和@Resource注解以及有啥区别...

同一类型多个@Bean报错问题

引出一个问题如果同一个类型有多个@Bean

换句话说就是在依赖注入的时候,我们注入一个Bean的时候,Spring中有多个Bean的类型与这个Bean的类型是一样的,但名称不同(Bean名称是唯一的) 这样会有什么问题呢?

这样说可能还是有一点抽象,我们就来举一个例子把.

比如我现在要注入一个名字为user的对象/Bean

@Autowired
private User user;

但是Spring中存在多个User类型的Bean. 比如下面:

@Configuration
public class UserBeans {
    @Bean(name = "user_1")
    public User user1(){
        User user = new User();
        user.setId(21);
        user.setAge(19);
        user.setName("UserBeans-->张三");
        return user;
    }
    @Bean(name = "user_2")
    public User user2(){
        User user = new User();
        user.setId(21);
        user.setAge(19);
        user.setName("UserBeans-->张三");
        return user;
    }
}
//------------StudentUserBeans与上面不是一个类---------
@Configuration
public class StudentUserBeans {
    @Bean(name = "stu_user1")
    public User user1(){
        User user = new User();
        user.setId(21);
        user.setAge(19);
        user.setName("StudentUserBeans-->张三");
        return user;
    }
}

现在有三个类型为User的Bean,但是三个Bean的名称并不一样,因为Spring中规定Bean的名称(也就是id)是唯一的.

当我们运行的时候会发生什么呢???

什么办法可以解决呢 ?

最简单最直接的办法就是,你在存储一个名称为user的Bean,或者将一个Bean的名称修改为Bean.

如果我非要使用那三个其中一个Bean呢?该怎么办?

有两种方法 :

  • 第一种方法 : 使用Resource注解使用自带的name参数来指定使用的Bean名称
  • 第二种方法 : 使用AutoWired注解注入,并且使用Qualifier来进行筛选
  • 第三种方法 : 使用primary注解

我先分别讲解这几个注解,然后在来解决这个问题

@Resource注解

@Resource的查找顺序

既指定name又指定type

如果既指定name又指定type,他就会在Spring查找name和type唯一匹配的bean,如果没有找到就会抛出异常.

只指定name

如果只指定了name的情况,他就会在Spring中查找name唯一匹配的bean,如果找到了则自动装配,没有找到则抛出异常,

只指定type

如果只指定了type,那么在Spring中查找type唯一匹配的bean,如果没有找到就抛出异常.

既没有指定name,也没有指定type

好我们在来整体总结一下 :

依赖注入的功能,是通过先在 Spring IoC 容器中查找对象(分为类型和名称两种查找方式),再将对象注入引入到当前类中

@Resource的查找顺序分为如下四种方式 :

  • 当指定name的时候,按照name唯一匹配的bean进行查找,如果查找到了则进行自动装配,否则抛出异常
  • 当执行type的时候,按照type唯一匹配的bean进行查找,如果查找到了则进行自动装配,否则抛出异常
  • 当既指定name又指定type的时候,按照name和type进行唯一匹配bean进行查找,如果查找到了则进行自动装配,否则抛出异常
  • 当既没有指定name,也没有指定type的时候,先按照name进行查找,如果查找到了就进行自动装配,如果没有查找到,继续按照类型去查找,如果查找到了则进行自动装配,如果没有查找到或者查找出多个bean,那么就抛出异常---->@Resource默认装配顺序

接着我们趁热打铁继续讲解@Resource注解

@Resource注解也可以实现依赖注入(@Resource注解是JDK提供的),但是也与AutoWired有一些区别.

@Resource注解实现依赖注入

@Resource注解实现属性注入

@Resource注解实现setter注入

@Resource注解并不能实现构造方法注入

@Resource注解不能实现构造方法注入,原因是Resource的执行时机比构造方法执行时机晚一些.

@Resource的来源

@Resource是JDK提供的一个注解,遵循JSR-250规范(Java 250 规范提案.

所以@Resource注解适用于所有的Java框架

@Resource的方法参数

@Resource注解提供多个参数,最重要的就是name和type.

@Resource注解的应用范围

@AutoWired

@AutoWired注解也是可以将依赖的对象注入到当前对象中.

我们接下来详细分析一下@AutoWired重要的几点

@AutoWired查找顺序

@AutoWired默认是先按照类型进行匹配Bean,如果匹配了多个Bean就按照name进行匹配,如果还是匹配了多个Bean就会抛出异常.

我们仔细分析@AutoWired的装配顺序

  • 首先先会按照类型进行匹配,如果匹配到了一个唯一Bean就进行自动装配,如果没有匹配到则抛出异常
  • 如果根据类型匹配出多个Bean,就看是否配置了@Qualifier注解
  • 如果没有配置,则默认会按照名称进行匹配,如果查找到了,则会进行自动装配,如果没有查找到就会抛出异常
  • 如果配置了@Qualifier注解则会根据它的参数的名称进行匹配,如果匹配到了则进行自动装配,否则就会抛出异常

@AutoWired依赖注入方式

使用@AutoWired可以实现三种注入,属性注入,setter注入,构造方法注入.

属性注入

@Autowired //使用一个AutoWired这样的一个注解---->自动装配的意思
private UserService userService;//UserService成员属性

属性注入的优点和缺点

优点 :

  • 属性注入只需要在属性上加一个@AutoWired注解,写法简便,可读性高,易维护.

缺点 :

  • 1.不能注入final修饰的属性.

为啥呢 ?

  • 因为我们知道JDK是我们最底层的框架,spring是上层,使用spring也要依赖java的,所以要遵循Java的规范,Java固定被final修饰的属性1.在定义的时候就进行赋值 2.在构造方法内部进行赋值.

所以,是因为不满足Java的规范

  • 2.属性注入只能在IOC容器才能使用(类与IOC容器高度耦合),使用其他容器/框架的时候不能使用属性注入(通用性不好)

  • 3.更容易违背单一职责原则

啥是单一职责原则呢 ?

单一职责原则的核心思想 : 一个类最好只做一件事,只有一个引起它变化的原因

换句话说,类只有单一功能,不要为类实现过多的功能点,以保证实体只有一个引起职责变化的原因

一个类只做一件事,要么做A事情,要么做B事情.只做一件事情

为什么说属性注入更容易违背单一职责原则呢 ?

  • 由于属性注入使用起来简便,这样就更容易使得开发者在类中注入多个对象,就可能会导致滥用的概率大大提高,所以违背单一职责原则的概率就大大提高-->更容易违背 不是一定违背,

setter注入

Setter注入的优缺点

优点 :

  • setter注入满足单一设计/职责原则.

因为setter方法的特性,一个setter方法只对应一个对象,不会有注入多个对象的可能性,所以满足单一设计/职责原则

缺点 :

  • 不能注入final修饰的对象

还是与属性注入的解释是一样的,原因就是JDK是我们最底层的框架,Spring作为上层,要基于JDK/Java的,所以要满足Java的规范,java规定,被final修饰的属性1.在定义的时候进行赋值2.在构造方法内部进行赋值

  • 注入的对象可能会被修改

由于setter方法是可以被多次调用的,有修改的风险,所以注入的对象就可能被修改.

构造方法注入

构造方法注入的优缺点

优点 :

构造方法最牛,上面的缺点,都是俺构造方法的优点.

就比如,属性注入和setter注入都不能解决注入final修饰的属性问题,那对于构造方法注入就能够解决

  • 能够注入final修饰的属性

为什么构造方法可以注入final修饰的属性呢?

原因还是一样的,因为满足Java的规范,被final修饰的属性 一个是定义的时候就进行赋值,一个是在构造方法内部进行赋值.满足第二条,所以可以注入final修饰的属性.

  • 注入的对象不会被修改.

构造方法注入 注入的对象不会被修改,因为构造方法只会执行一次.

  • 构造方法注入是完全初始化的.

因为依赖注入是在构造方法内部执行的,而构造方法又是在类起初创建的时候就执行的,所以会被完全初始化

  • 它的通用性会更好

构造方法注入因为基于java的,JDK是最底层框架,所以无论在哪一个容器/框架都可以适用

缺点 :

  • 构造方法可以注入多个对象,也就违背了单一设计原则
  • 写法不简便

官方建议

在Spring4.2之前推荐的注入用法就是setter注入,因为setter注入更加符合单一设计/职责原则

在Spring4.2之后官方就推荐使用构造方法注入的方式(因为它的优点).如果要传入太多参数就需要考虑单一设计原则问题了.

但是我们在开发的时候依然会使用属性注入的方式,因为写法很简便.

@AutoWired来源

@AutoWired注解是来自于Spring的,也就是来自于IOC容器,换句话说,@AutoWired注解只支持spring框架,不能在其他框架使用@AutoWired

@AutoWired方法参数

@AutoWired就只有一个required的参数.

required参数 : 设置为true的时候认为可以自动注入 ,false就是关闭自动注入

@AutoWired注解作用范围

这个源码可以看的出来.

根据源码可以看的出来,@AutoWired注解支持构造方法,成员变量,成员方法以及注解上..

@AutoWired与@Resource的区别

  • 来源不同

@AutoWired注解来自于Spring,只支持Spring框架,不能在其他框架中使用

@Resource注解是JDK提供的遵循JSR-250规范,可以适用于所有的Java框架

  • 装配顺序不同

@AutoWired默认装配顺序是先按照类型进行匹配,如果匹配了多个Bean就在按照名称进行匹配,如果没有找到或者匹配到多个就会抛出异常,如果期间配置了@Qualifier注解就会按照它的参数进行匹配,如果匹配到了则进行自动装配,没有匹配就抛出异常

@Resource注解默认的装配顺序是先按照名称进行匹配,如果没有匹配或者匹配多个,则按照类型进行匹配,如果还没有匹配到或者匹配出多个则抛出异常.如果指定name则按照name进行唯一匹配,如果指定type则按照type进行唯一匹配,没有匹配到就抛出异常,如果既指定name也指定type那么就按照name和type进行唯一匹配,匹配到了则自动装配,没有匹配到则抛出异常.

  • 方法的参数不同

@AutoWired注解只有一个required参数,表示是否开启自动注入

@Resource注解有多个方法参数,最重要的2个参数是name和type

  • 注解应用的范围不同

@AutoWired注解可以加在成员变量,成员方法,方法参数及注解上

@Resource注解可以加在 类,成员变量,方法上.

  • 依赖注入的方式不同

@AutoWired注解支持属性注入,setter注入,构造方法注入

@Resource注解支持属性注入,setter注入,但是不支持构造方法注入

@Qualifier

Qualifier意思是合格者,一般跟Autowired配合使用,需要指定一个bean的名称,通过bean名称就能找到需要装配的bean。

我们一般是使用@AutoWired进行Bean的注入的,但是当有同一个类型多个Bean的时候,Spring就会抛出异常NoUniqueBeanDefinitionException

如下 :

我们就可以使用注解@Qualifier注解中填入我们想要装配Bean的名称,所以,通过将 @Qualifier 注解与我们想要指定特定的Bean名称一起装配,这样Spring就会从多个相同类型并满足装配的要求找出我们想要的Bean

如果@Primary和@Qualifier注解都在那么会优先执行@Qualifier

@primary

当我们使用自动配置的方式装配Bean时,如果这个Bean有多个候选者,假如其中一个候选者具有@Primary注解修饰,该候选者会被选中,作为自动配置的值。

如果@Primary和@Qualifier注解都在那么会优先执行@Qualifier

解决同一类型Bean报错的问题

使用Resource注解解决

使用Resource注解来解决上述问题,并仔细讲解Resource注解

使用@AutoWired注解 + @Qualifier注解解决

Qualifier意思是合格者,一般跟Autowired配合使用,需要指定一个bean的名称,通过bean名称就能找到需要装配的bean。

使用@primary注解解决

当我们使用自动配置的方式装配Bean时,如果这个Bean有多个候选者,假如其中一个候选者具有@Primary注解修饰,该候选者会被选中,作为自动配置的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/61152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网课题库接口调用方法

网课题库接口调用方法 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(点…

QT对象树机制

Qt提供了对象树机制,能够自动、有效的组织和管理继承自QObject的Qt对象。 每个继承自QObject类的对象通过它的对象链表(QObjectList)来管理子类对象,当用户创建一个子对象时,其对象链表相应更新子类对象信息&#xff0…

Docker快速入门

容器Docker技术的演进 1.曾经部署应用,使用物理机部署,这可能会因为不同应用所依赖的版本号不同,不得已购买一套全新的机器,所以成本高、部署慢、资源浪费、难以迁移和拓展、可能会被限定硬件厂商。 2.之后引入了VMVare&#xff…

使用JPA和Hibernate查询分页

介绍 受到我最近给出的StackOverflow答案的启发,我决定是时候写一篇关于使用JPA和Hibernate时查询分页的文章了。 在本文中,您将了解如何使用查询分页来限制 JDBC大小并避免获取不必要的数据。ResultSet 如何在#Hibernate中使用查询分页来限制 JDBC 结…

pytorch深度学习实战lesson32

第三十二课 分布式训练 这个是15年的时候沐神在 CMU 装的一个小机群,里面有30台机器,各机群有大概60块 GPU , 60块 GPU一共花了三四万美金的样子,就是大概20万人民币。沐神表示最亏的是当年他们跑了太多深度学习的实验&#xff0c…

C语言-const char*,char const*,char *const理解

By: Ailson Jack Date: 2022.12.04 个人博客:http://www.only2fire.com/ 本文在我博客的地址是:http://www.only2fire.com/archives/150.html,排版更好,便于学习,也可以去我博客逛逛,兴许有你想要的内容呢。…

传奇外网开服教程-GEE传奇外网全套架设教程

版本不同,所用的引擎和配置也会不同,但是架设方法都是大同小异,今天明杰给大家分享GEE引擎的外网架设教程。​ 需要准备的东西:DBC200版本,补丁,客户端,服务器,备案域名&#xff0c…

【Typora】Typora 新手入门参数配置记录

目录 写在前面 更改图片大小 更换高亮背景 更换主题 写在前面 最近发现一款记笔记的软件——Typora,极简清爽的外观一下子就把我给吸引住了,它支持Markdown 的格式记录,可以让笔记更加有条理、美观,至于 typora 的一些写作语法…

Android入门第43天-Activity与Activity间的互相传值

介绍 今天的课程会比较好玩,我们在之前的Service篇章中看到了一种putExtras和getExtras来进行activity与service间的传值。而恰恰这种传值其实也是Android里的通用传值法。它同样可以适用在activity与activity间传值。 Android中的传值 传单个值 传多个值 具体我…

Spring注解(简便地使用 Bean )

目录 0. 前置工作 1. 将 Bean 存储到容器 2. 对象注入&#xff08;对象装配&#xff09;【从容器中将对象读取出来】 0. 前置工作 创建Maven项目后&#xff0c;在pom.xml中添加Spring所必须的依赖。 <dependencies><dependency><groupId>org.springframe…

22个每个程序员都应该知道的 Git 命令

在这篇文章中&#xff0c;我写了一个快速学习 git 命令的备忘单。它将包括开发人员每天使用的命令&#xff0c;如 git add、git commit、git pull、git fetch&#xff0c;并共享其他有用的 git 命令。 我一直使用Git的一些命令&#xff0c;今天这个列表清单&#xff0c;希望也…

LC-6256. 将节点分成尽可能多的组(二分图判定+BFS)【周赛322】

6256. 将节点分成尽可能多的组 难度困难8 给你一个正整数 n &#xff0c;表示一个 无向 图中的节点数目&#xff0c;节点编号从 1 到 n 。 同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间有一条 双向 边。注意给定的图可能是不…

第4章 R语言编程基础——数据整理与预处理

目录 4.1 经济/金融数据库 4.1.1 金融数据与数据库 4.1.2 国外金融数据库概况 4.1.3 国内金融数据库概况 4.1.4 数据的主要内容 4.2 数据格式 4.3 数据的导入 4.3.1 从控制台上输入数据 4.3.2 上市公司财务报表信息读取 4.4 [数据的预处理] 4.1.1 时序数据的预处理 4.1.2…

[附源码]Python计算机毕业设计Django汽车租赁管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

WEB前端网页设计 HTML网页代码 基础参数(二)

html文件调用css文件 <link rel"stylesheet" type"text/css" href"css文件相对路径"/> 设置颜色 Style"color:green;" 设置字体大小 font-size:50px; 设置边框 border&#xff1a;groove&#xff1b; 设置长、宽 heigh…

【通信原理】数字基带传输的线路码型

数字基带传输的线路码型 简单介绍数字基带传输的线路码型的信号波形的特点&#xff0c;以及生成方法。注意观察频谱。文末附Matlab代码。 以下包括双极性NRZ、单极型NRZ、双极型RZ、单极型RZ、差分码&#xff0c;曼切斯特码/数字双相码、密勒码、CMI码、AMI码、HDB3码。 参数…

Spring中Bean的生命周期

先直接说出过程&#xff0c;再来演示具体的操作 过程 简化来说就是 1、首先是实例化Bean&#xff0c;当客户向容器请求一个尚未初始化的bean时&#xff0c;或初始化bean的时候需要注入另一个尚末初始化的依赖时&#xff0c;容器就会调用doCreateBean()方法进行实例化&#xf…

Java多线程之:队列同步器AbstractQueuedSynchronizer原理剖析

Java多线程之&#xff1a;队列同步器AbstractQueuedSynchronizer原理剖析 文章目录Java多线程之&#xff1a;队列同步器AbstractQueuedSynchronizer原理剖析一、AQS的核心思想二、AQS中关键的内部结构一、Node内部类二、CLH队列三、同步状态 state四、Condition条件队列三、AQS…

houdini 之copy to points

将第一个输入中的几何图形复制到第二个输入的点上。 属性备注Source Group几何体来源Target Points要复制到的目标点集合Show Guide Geometry是否显示该操作预览流程Pack and Instance在复制之前将输入几何体打包到嵌入式打包图元中。这导致输入几何被每个副本共享&#xff08;…

跟着实例学Go语言(一)

本教程全面涵盖了Go语言基础的各个方面。一共80个例子&#xff0c;每个例子对应一个语言特性点&#xff0c;非常适合新人快速上手。 教程代码示例来自go by example&#xff0c;文字部分来自本人自己的理解。 本文是教程系列的第一部分&#xff0c;共计20个例子、约1万字。 目…