Spring Bean自动装配:深入解析与实战应用

 

 

何为自动装配

在使用Spring框架配置bean时,我们通常需要为bean的属性设置值。如果不手动设置这些值,它们通常会被初始化为默认值(对于对象类型通常是null,对于基本类型如int则是0,boolean是false等)。自动装配的好处在于,我们不需要手动为每个依赖的bean设置值,Spring容器会根据配置在上下文中自动寻找并装配合适的值。

在Spring中,有几种不同的装配方式:

  1. XML配置:
    通过Spring的XML配置文件,我们可以显式地定义bean以及它们之间的依赖关系。这通常涉及使用<bean>标签来定义bean,并通过<property><constructor-arg>标签来设置bean的属性或构造器参数。

  2. Java配置(或称为注解配置):
    从Spring 3.0开始,我们可以使用Java类来定义bean和它们之间的依赖关系,而不是使用XML。这通常涉及使用@Configuration注解来标记一个类作为配置类,并使用@Bean注解来标记一个方法作为bean的工厂方法。

  3. 自动装配:
    Spring提供了自动装配功能,可以自动解析和注入bean之间的依赖关系。这可以通过在bean上使用@Autowired@Resource@Inject等注解来实现。这些注解告诉Spring容器在创建bean时自动查找并注入所需的依赖项。

    • @Autowired:Spring特有的注解,用于自动装配bean。默认情况下,它按类型(byType)自动装配。当存在多个相同类型的bean时,可以使用@Qualifier注解来指定要注入的bean的名称。

    • @Resource:Java EE的注解,也支持自动装配。与@Autowired不同,@Resource默认按名称(byName)查找bean,但也可以按类型查找(如果同时指定了名称和类型)。

    • @Inject:这是JSR-330规范的一部分,与@Autowired类似,但它是Java标准的一部分,不仅限于Spring。

 

环境准备

先来定义好三个 POJO 类,Teacher、Student、Study。并且有一个关系就是 Teacher拥有学生和学科。

package com.JavaClass.pojo;public class student{public void shout(){System.out.println("我是学生");}
}
package com.JavaClass.pojo;public class study {public void shout(){System.out.println("I like study");}
}
package com.JavaClass.pojo;public class teacter{private Student student;private Study study;private String name;/* getter/setter 和 toString */}

Spring 配置文件部分:

在该项目的resources目录下,创建一个spring-config.xml 用来配置文件spring-config.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="student" class="com.JavaClass.pojo.Student"/>
<bean id="study" class="com.JavaClass.pojo.Study"/>
<bean id="teacher" class="com.JavaClass.pojo.Teacher"><property name="name" value="JAVA学习课堂/><property name="cat" ref="cat"/><property name="dog" ref="dog"/></bean>
</beans>

在该项目的src/test/java目录下,创建一个MyTest测试类,用来测试代码。

import com.JavaClass.pojo.Teacher;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {@Testpublic void test(){//解析beans.xml文件,IOC容器生成并管理相应的Bean对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");//通过Spring的上下文对象,从IOC容器中获取Bean对象Teacher person = context.getBean("teacher", Teacher.class);//调用Bean对象的方法person.getStudent().shout();person.getStudy().shout();}
}

 

测试默认装配的结果如图:

 

e2284df81442845c4d0f72e311b2953c.png

配置实现自动装配

自动装配在Spring中有几种不同的方式,主要包括:

  1. byName:
    根据属性名自动装配。Spring容器会查找与bean的属性名相同的另一个bean的定义,并将其自动装配到当前bean中。

  2. byType:
    根据属性类型自动装配。Spring容器会查找与bean的属性的类型相匹配的bean定义,如果有多个相同类型的bean,则会抛出异常,除非指定了其他方式(如使用@Qualifier注解)来消除歧义。

  3. constructor:
    基于构造函数的自动装配。与基于类型的自动装配类似,但它是应用于构造函数的参数。Spring容器会查找与构造函数的参数类型相匹配的bean定义,并使用这些bean来实例化当前的bean。

byName

在使用Spring框架的自动装配特性时,若启用了byName模式,则容器会按照特定规则查找与bean属性匹配的bean定义。具体而言,它会根据类中定义的setter方法名(去掉set前缀,并将剩余部分的首字母转换为小写)来寻找一个具有相同ID的bean定义。例如,如果 theacher 类中包含一个名为setStudent的setter方法,并且Spring的配置文件中存在一个ID为student的bean定义,那么Spring容器在启用byName自动装配后,会自动将ID为student的bean注入到Teacher类的student属性中。

 

操作:修改  spring-config.xml  文件中的代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="student" class="com.JavaClass.pojo.Student"/><bean id="study" class="com.JavaClass.pojo.Study"/><!--加上了 person 的 bean 的 autowired 属性并去掉了手动装配的 cat 和 dog --><bean id="teacher" class="com.JavaClass.pojo.Teacher" autowire="byName"><property name="name" value="Java学习课堂"/></bean><!--    <bean id="person" class="com.JavaClass.pojo.Person">--><!--        <property name="name" value="Java学习课堂"/>--><!--        <property name="cat" ref="cat"/>--><!--        <property name="dog" ref="dog"/>--><!--    </bean>-->
</beans>
 

结果依旧相同,证明这样根据 byName 的代码是没问题的。

 

9423d3f7181b526677df1d73c05417b8.png

byType

byType模式会根据bean中所需依赖的类型,在容器上下文中自动寻找匹配的bean定义并进行装配。如果容器中存在一个或多个与所需依赖类型相匹配的bean,Spring将尝试将它们自动注入到当前bean中。

改动下 spring-config.xml 配置文件中 id 为 teacher  的 bean,配置成byType 模式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="student" class="com.JavaClass.pojo.Student"/><bean id="study" class="com.JavaClass.pojo.Study"/><!--加上了 person 的 bean 的 autowired 属性并去掉了手动装配的 cat 和 dog --><bean id="teacher" class="com.JavaClass.pojo.Teacher" autowire="byType"><property name="name" value="Java学习课堂"/></bean>
</beans>
 

注:byType自动装配时,存在一个潜在的问题,即当容器中存在多个相同类型的bean时,由于不是基于唯一的id来匹配,而是根据类型进行匹配,Spring将无法确定应该注入哪一个bean,这会导致一个异常。

 

afb010a05fa44102dc016e4e4ba8121d.png

 

8887a9dc647bba56f74dc6d4ef829bc1.png

 

使用注解实现自动装配

使用注解的准备

如果使用注解我们还需要对原本的配置文件做一些修改,增加约束,来支持通过注解的形式实现自动装配。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><!-- 开启注解支持 --><context:annotation-config/><bean id="student" class="com.JavaClass.pojo.Student"/><bean id="study" class="com.JavaClass.pojo.Study"/><bean id="teacher" class="com.JavaClass.pojo.Teacher"/></beans>

@AutoWired注解的使用

在 POJO 类需要自动装配的属性上加 @AutoWired 注解实现自动装配。

package com.JavaClass.pojo;import org.springframework.beans.factory.annotation.Autowired;public class Teacher {@Autowiredprivate Student student;@Autowiredprivate Study study;private String name;/* getter/setter 和 toString */}

执行测试代码,结果如下:

 

9423d3f7181b526677df1d73c05417b8.png

@Qualifier

当在Spring配置中定义了同一个类的多个bean,并使用@Autowired注解进行自动装配时,由于@Autowired默认采用按类型(byType)的装配方式,Spring框架将无法直接确定应该注入哪一个bean实例,因为存在多个相同类型的候选者。

可以使用@Qualifier注解:通过在@Autowired注解旁边添加@Qualifier注解,可以指定要注入的bean的名称。例如,如果有一个名为myBeanA和myBeanB的相同类型的bean,你可以在@Autowired注解旁边使用@Qualifier("myBeanA")来指定注入myBeanA。

 

测试:在配置文件中增加一个 Student 的 bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><!-- 开启注解支持 --><context:annotation-config/><bean id="student" class="com.JavaClass.pojo.Student"/><bean id="student2" class="com.JavaClass.pojo.Student"/><bean id="study" class="com.JavaClass.pojo.Study"/><bean id="teacher" class="com.JavaClass.pojo.Teacher"/></beans>

Teacher 类中配合 @Qualifier  注解

package com.JavaClass.pojo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;public class Teacher{@Autowired@Qualifier("student")private Student student;@Autowiredprivate Study study;private String name;/* getter/setter 和 toString */
}

测试代码结果如下“

 

9423d3f7181b526677df1d73c05417b8.png

@Resource

在Spring框架中,@Resource注解用于自动装配bean,它结合了@Autowired(按类型装配)和@Qualifier(按名称装配)的功能。在bean的自动装配过程中,可以使用@Resource注解的name属性来指定要注入的bean的名称,这个name属性的作用类似于@Qualifier注解的value属性,用于消除类型相同的bean之间的歧义。同时,@Resource还提供了额外的功能,如根据JNDI名称查找资源。

@Resource 与 @AutoWired 的不同在于:

  • @Resource 默认是按照 名称 来装配注入的,当找不到与名称匹配的 bean 才会按照类型来装配注入。

  • @Autowired 默认是按照 类型 装配注入的,如果想按照名称来装配注入,则需要结合 @Qualifier 一起使用;

 

通过 @Resource 注解来进行自动装配 bean

import javax.annotation.Resource;public class Teacher{@Resourceprivate Student student;@Resourceprivate Study study;private String name;/* getter/setter 和 toString */

 

<bean id="student1" class="com.JavaClass.pojo.Student"/>
<bean id="student2" class="com.JavaClass.pojo.Student"/>
<bean id="study" class="com.JavaClass.pojo.Study"/>
<bean id="teacher" class="com.JavaClass.pojo.Teacher"/>
运行结果如下:

 

98df8891b9b58c9db001e9f663602c9e.png

 @Resource 默认是通过 id 来查找 bean,而配置的两个 cat 的 bean 没有一个名称为默认查找的 cat,故而创建失败。

修改 @Resource,加入参数

@Resource(name = "student1")
private Student student;
@Resource
private Study study;
private String name;

再次执行程序:

 

9423d3f7181b526677df1d73c05417b8.png

程序没问题了

 @Resource总结:

@Resource 注解在 Spring 中默认先尝试通过 bean 的名称(byName)进行自动装配。如果容器中不存在与指定名称相匹配的 bean,则会退回到通过 bean 的类型(byType)进行匹配。但是,如果在类型匹配时找到多个相同类型的 bean,并且没有通过 name 属性指定具体的 bean 名称来消除歧义,或者根本找不到任何该类型的 bean,那么自动装配将失败,并会抛出一个异常。

 

 

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

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

相关文章

(超详细)YOLOV7改进-Soft-NMS(支持多种IoU变种选择)

1.在until/general.py文件最后加上下面代码 2.在general.py里面找到这代码&#xff0c;修改这两个地方 3.之后直接运行即可

网页设计软件Bootstrap Studio6.7.1

Bootstrap Studio是一个适用于Windows的程序,允许您使用流行的fre***orca Bootstrap创建和原型网站。您可以将现成的组件拖动到工作区并直观地自定义它们。该程序生成干净和语义的PDF、CSS和JS代码,所有Web浏览器都支持这些代码。 Bootstrap Studio有一个漂亮而强大的界面,它…

DataWorks重磅推出全新资源组2.0,实现低成本灵活付费和动态平滑扩缩容

背景简介 DataWorks资源组为DataWorks上的各个功能模块提供计算资源&#xff0c;属于付费服务。 资源组属于DataWorks的基础组件&#xff0c;是客户正常使用DataWorks的前提。 资源组直接影响到相关功能是否正常运行&#xff0c;以及运行的效率和稳定性。 此前DataWorks资源…

ImportError: attempted relative import beyond top-level package报错,解决方法

1.如下图所示&#xff0c;在conftest.py页面采用相对路径去引用包&#xff0c;运行提示报错信息 目录结构: D:. ├─common ├─config ├─image ├─logFile ├─page │ └─basePage.py └─test_cases└─conftest.py从目录结构中我们可以看到conftest.py文件和basePage…

如何免费的去使用connectedpapers?

免费使用connectedpapers 1. 打开谷歌浏览器2. 按住ctrlshiftN,进入无痕模式3. 不需要登录&#xff08;也就是访客模式&#xff09;4. 两次用完&#xff0c;关闭无痕模式&#xff08;继续重复步骤 2 - 4&#xff09; 1. 打开谷歌浏览器 2. 按住ctrlshiftN,进入无痕模式 输入网…

使用Github API获取排名

看到有人使用Github 提供的API做了GitHub rank的网站&#xff0c;由于以前没有使用过Github的API&#xff0c;所以打算自己动手尝试一下。在线效果 1. Token 生成 使用API前需要先申请开发者Token&#xff0c;在Settings --> Developer settings --> Personal access t…

对的礼物送给对的人,送礼物的技巧和学问

一、教程描述 无论是商务往来&#xff0c;还是求人办事&#xff0c;送礼都是不可或缺的一种交际手段。想要建立好的人脉关系网&#xff0c;想要把事儿办成&#xff0c;一定要把对的礼物送给对的人&#xff0c;否则必是竹篮打水一场空。送礼是一门学问&#xff0c;同时&#xf…

使用babel将es6语法进行转换es2015

使用babel将es6语法进行转换es2015 1、npm初始化 npm init -y2、全局安装babel-cli 和 browserify npm i babel-cli browserify -g3、项目根目录下执行 npm i babel-preset-es2015 --save-dev4、项目根目录下新建.babelrc {"presets": ["es2015"] }5、…

【C语言】函数执行背后的秘密:函数栈帧的创建和销毁超详解

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1. 什么是函数栈帧 2. 理解函数栈帧能解决什么问题呢&#xff1f; 3. 函数栈帧的创建和销毁解析 3.1 什么是栈&#xff1f; 3.2 认识相关寄存器和汇编指…

讨论顺序表

讨论顺序表 C中的vector模拟实现成员变量尾插数据push_back扩容reserve 构造函数和析构函数拷贝构造函数指定位置插入数据指定位置删除数据迭代器失效完整代码 C中&#xff0c;vector是可以改变大小的数组的序列容器。可以看做底层就是一个数组&#xff0c;容量满时扩容。 C中的…

Android集成高德地图SDK(1)

1.新建Android应用&#xff0c;确定应用包名 2.注册高德开放平台&#xff0c;打开控制台页面&#xff0c;应用管理&#xff0c;我的应用&#xff0c;创建新应用 3.添加Key 4.获取SHA1码 找到Android Studio自带的keytool 将其拖到cmd中&#xff0c;输入命令 -v -list -keystor…

【单片机毕业设计选题24024】-房间自动除湿控制系统

系统功能: 系统分为手动和自动模式&#xff0c;上电默认为自动模式。自动模式下如果获取到湿度 值大于设定的湿度值则自动打开风扇&#xff0c;手动模式下手动开关风扇。 系统上电后显示“欢迎使用除湿控制系统请稍后”&#xff0c;两秒钟后进入主页面显示。 第一行显示系统…

Python-矩阵元素定位

[题目描述] 小理得到了一个 n 行 m 列的矩阵&#xff0c;现在他想知道第 x 行第 y 列的值是多少&#xff0c;请你帮助他完成这个任务。输入格式&#xff1a; 第一行包含两个数 n 和m &#xff0c;表示这个矩阵包含 n行 m 列。从第 2 行到第 n1 行&#xff0c;每行输入 m 个整数…

聚观早报 | 荣耀Magic V Flip开售;亚马逊将升级Alexa

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月24日消息 荣耀Magic V Flip开售 亚马逊将升级Alexa HarmonyOS NEXT Beta发布 懂车帝上线独家片场计划 苹果正…

基于堆叠长短期记忆网络 Stacked LSTM 预测A股股票价格走势

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…

羊大师:拒绝心灵内耗:走向高效与平和

在繁忙的生活中&#xff0c;我们时常感到疲惫不堪&#xff0c;仿佛心灵被无形的枷锁束缚&#xff0c;这就是精神内耗。它让我们在思考、决策和行动中犹豫不决&#xff0c;消耗着我们的精力和时间&#xff0c;让我们无法专注于真正重要的事情。然而&#xff0c;我们有能力打破这…

HCIP-数通 V1.0 培训教材总结01

HCIP-数通 V1.0 培训教材总结01 01 认识网络设备框式设备及其硬件模块盒式设备框式、盒式设备的区别网络设备逻辑架构网络设备对报文的处理流程 01 认识网络设备 框式设备及其硬件模块 S12700E-8 &#xff08;S-switch&#xff0c;交换机) &#xff08;8&#xff0c;业务槽位…

Redis通用命令详解

文章目录 一、Redis概述1.1 KEYS&#xff1a;查看符合模板的所有 key1.2 DEL&#xff1a;删除一个指定的 key1.3 EXISTS&#xff1a;判断 key 是否存在1.4 EXPIRE&#xff1a;给一个 key 设置有效期&#xff0c;有效期到期时该 key 会被自动删除1.5 TTL&#xff1a;查看一个 ke…

VPDBVE16E、VPDBVE32A、VPDBVE32B比例控制阀放大器

VPDBPC06A、VPDBPC06B、VPDBPC06C、VPDBPC06D、VPDBPC06E、VPDB08PC06100、VPDB08PC06200、VPDB08PC06315、VPDBVE16A、VPDBVE16B、VPDBVE16C、VPDBVE16D、VPDBVE16E、VPDBVE32A、VPDBVE32B、VPDBVE32C、VPDBVE32D、VPDBVE32E、VPDM2VE16A、VPDM2VE16B、VPDM2VE16C、VPDM2VE16D…

AWS中国IAM用户强制使用MFA

问题 需要对IAM用户强制使用MFA方式进行登陆。 步骤 创建强制MFA登陆策略 找到策略创建入口&#xff0c;如下图&#xff1a; 将下述内容json策略内容&#xff0c;复制到编辑器里面&#xff0c;具体内容和操作如下&#xff1a; {"Version": "2012-10-17&qu…