Spring学习笔记(三)——Spring依赖注入

news/2024/3/29 22:46:42/文章来源:https://www.cnblogs.com/worthmove/p/16634473.html

1.Spring Bean属性注入的几种方式

1.1构造函数注入

使用构造函数实现属性注入大致步骤如下:

  1. 在 Bean 中添加一个有参构造函数,构造函数内的每一个参数代表一个需要注入的属性;
  2. 在 Spring 的 XML 配置文件中,通过 <beans> 及其子元素 <bean> 对 Bean 进行定义;
  3. 在 <bean> 元素内使用 <constructor-arg> 元素,对构造函数内的属性进行赋值,Bean 的构造函数内有多少参数,就需要使用多少个 <constructor-arg> 元素。

示例如下:

Grade(Bean)类代码如下:

复制代码
public class Grade {private static final Log LOGGER = LogFactory.getLog(Grade.class);private Integer gradeId;private String gradeName;public Grade(Integer gradeId, String gradeName) {LOGGER.info("正在执行 Course 的有参构造方法,参数分别为:gradeId=" + gradeId + ",gradeName=" + gradeName);this.gradeId = gradeId;this.gradeName = gradeName;}@Overridepublic String toString() {return "Grade{" +"gradeId=" + gradeId +", gradeName='" + gradeName + '\'' +'}';}
}
复制代码

Student(Bean)类代码如下:

这里可以说Student类依赖于Grade类。

复制代码
public class Student {private static final Log LOGGER = LogFactory.getLog(Student.class);private int id;private String name;private Grade grade;public Student(int id, String name, Grade grade) {LOGGER.info("正在执行 Course 的有参构造方法,参数分别为:id=" + id + ",name=" + name + ",grade=" + grade);this.id = id;this.name = name;this.grade = grade;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", grade=" + grade +'}';}
}
复制代码

Beans.xml代码如下:

注意直接类型用value,自定义的引用类型用ref。

复制代码
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="student" class="net.biancheng.c.Student"><constructor-arg name="id" value="2"></constructor-arg><constructor-arg name="name" value="李四"></constructor-arg><constructor-arg name="grade" ref="grade"></constructor-arg></bean><bean id="grade" class="net.biancheng.c.Grade"><constructor-arg name="gradeId" value="4"></constructor-arg><constructor-arg name="gradeName" value="四年级"></constructor-arg></bean>
</beans>
复制代码

主类代码如下:

复制代码
public class MainApp {private static final Log LOGGER = LogFactory.getLog(MainApp.class);public static void main(String[] args) {//获取 ApplicationContext 容器ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//获取名为 student 的 BeanStudent student = context.getBean("student", Student.class);//通过日志打印学生信息LOGGER.info(student.toString());}
}
复制代码

控制台输出如下:

复制代码
十二月 16, 2021 4:38:42 下午 net.biancheng.c.Grade <init>
信息: 正在执行 Course 的有参构造方法,参数分别为:gradeId=4,gradeName=四年级
十二月 16, 2021 4:38:42 下午 net.biancheng.c.Student <init>
信息: 正在执行 Course 的有参构造方法,参数分别为:id=2,name=李四,grade=Grade{gradeId=4, gradeName='四年级'}
十二月 16, 2021 4:38:42 下午 net.biancheng.c.MainApp main
信息: Student{id=2, name='李四', grade=Grade{gradeId=4, gradeName='四年级'}}
复制代码

1.2 setter注入

使用 setter 注入的方式进行属性注入,大致步骤如下:

  1. 在 Bean 中提供一个默认的无参构造函数(在没有其他带参构造函数的情况下,可省略),并为所有需要注入的属性提供一个 setXxx() 方法;
  2. 在 Spring 的 XML 配置文件中,使用 <beans> 及其子元素 <bean> 对 Bean 进行定义;
  3. 在 <bean> 元素内使用  <property> 元素对各个属性进行赋值。

示例如下:

Student(Bean)类代码如下:

复制代码
public class Student {private static final Log LOGGER = LogFactory.getLog(Student.class);private int id;private String name;private Grade grade;//无参构造方法,在没有其他带参构造方法的情况下,可以省略public Student() {}//id 属性的 setter 方法public void setId(int id) {LOGGER.info("正在执行 Student 类的 setId() 方法…… ");this.id = id;}//name 属性的 setter 方法public void setName(String name) {LOGGER.info("正在执行 Student 类的 setName() 方法…… ");this.name = name;}public void setGrade(Grade grade) {LOGGER.info("正在执行 Student 类的 setGrade() 方法…… ");this.grade = grade;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", grade=" + grade +'}';}
}
复制代码

Grade(Bean)类代码如下:

复制代码
public class Grade {private static final Log LOGGER = LogFactory.getLog(Grade.class);private Integer gradeId;private String gradeName;/*** 无参构造函数* 若该类中不存在其他的带参构造函数,则这个默认的无参构造函数可以省略*/public Grade() {}public void setGradeId(Integer gradeId) {LOGGER.info("正在执行 Grade 类的 setGradeId() 方法…… ");this.gradeId = gradeId;}public void setGradeName(String gradeName) {LOGGER.info("正在执行 Grade 类的 setGradeName() 方法…… ");this.gradeName = gradeName;}@Overridepublic String toString() {return "Grade{" +"gradeId=" + gradeId +", gradeName='" + gradeName + '\'' +'}';}
}
复制代码

Beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="student" class="net.biancheng.c.Student"><!--使用 property 元素完成属性注入name: 类中的属性名称,例如 id,namevalue: 向属性注入的值 例如 学生的 id 为 1,name 为张三--><property name="id" value="1"></property><property name="name" value="张三"></property><property name="grade" ref="grade"></property></bean><bean id="grade" class="net.biancheng.c.Grade"><property name="gradeId" value="3"></property><property name="gradeName" value="三年级"></property></bean>
</beans>
复制代码

Main方法如上,输出信息一致。

1.3 短命名空间注入

本质上是对前两种方法的一个简写形式。

我们在通过构造函数或 setter 方法进行属性注入时,通常是在 <bean> 元素中嵌套 <property> 和 <constructor-arg> 元素来实现的。这种方式虽然结构清晰,但书写较繁琐。
Spring 框架提供了 2 种短命名空间,可以简化 Spring 的 XML 配置,如下表。

 p命名空间注入

p 命名空间是 setter 方式属性注入的一种快捷实现方式。通过它,我们能够以 bean 属性的形式实现 setter 方式的属性注入,而不再使用嵌套的 <property> 元素,以实现简化 Spring 的 XML 配置的目的。
首先我们需要在配置文件的 <beans> 元素中导入以下 XML 约束。

xmlns:p="http://www.springframework.org/schema/p"

在导入 XML 约束后,我们就能通过以下形式实现属性注入。

<bean id="Bean 唯一标志符" class="包名+类名" p:普通属性="普通属性值" p:对象属性-ref="对象的引用">

Bean类省略了,看一下Beans.xml的代码写法:

复制代码
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="employee" class="net.biancheng.c.Employee" p:empName="小李" p:dept-ref="dept" p:empNo="22222"></bean><bean id="dept" class="net.biancheng.c.Dept" p:deptNo="1111" p:deptName="技术部"></bean>
</beans>
复制代码

c命名空间注入

c 命名空间是构造函数注入的一种快捷实现方式。通过它,我们能够以 <bean> 属性的形式实现构造函数方式的属性注入,而不再使用嵌套的 <constructor-arg> 元素,以实现简化 Spring 的 XML 配置的目的。
首先我们需要在配置文件的 <beans> 元素中导入以下 XML 约束。

xmlns:c="http://www.springframework.org/schema/c"

在导入 XML 约束后,我们就能通过以下形式实现属性注入。

<bean id="Bean 唯一标志符" class="包名+类名" c:普通属性="普通属性值" c:对象属性-ref="对象的引用">

Beans.xml中代码如下:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="employee" class="net.biancheng.c.Employee" c:empName="小胡" c:dept-ref="dept" c:empNo="999"></bean><bean id="dept" class="net.biancheng.c.Dept" c:deptNo="2222" c:deptName="测试部"></bean>
</beans>

2.Spring注入内部Beans

之前我们在处理类的依赖时(也就是一个类中保持有另外一个类的对象),使用的是ref属性进行链接到依赖类的id,我们还可以使用内部注入的方式来完成依赖注入。

来看一个代码示例:

TextEditor类代码文件(Bean):

public class TextEditor {private SpellChecker spellChecker;// a setter method to inject the dependency.public void setSpellChecker(SpellChecker spellChecker) {System.out.println("Inside setSpellChecker." );this.spellChecker = spellChecker;}  // a getter method to return spellCheckerpublic SpellChecker getSpellChecker() {return spellChecker;}public void spellCheck() {spellChecker.checkSpelling();}
}

下面是另一个依赖的类文件 SpellChecker.java 内容:

public class SpellChecker {public SpellChecker(){System.out.println("Inside SpellChecker constructor." );}public void checkSpelling(){System.out.println("Inside checkSpelling." );}   
}

主文件内容如下:

public class MainApp {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");TextEditor te = (TextEditor) context.getBean("textEditor");te.spellCheck();}
}

Beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- Definition for textEditor bean using inner bean --><bean id="textEditor" class="com.tutorialspoint.TextEditor"><property name="spellChecker"><bean id="spellChecker" class="com.tutorialspoint.SpellChecker"/></property></bean>

3.Spring注入集合

你已经看到了如何使用 value 属性来配置基本数据类型和在你的 bean 配置文件中使用<property>标签的 ref 属性来配置对象引用。这两种情况下处理奇异值传递给一个 bean。

现在如果你想传递多个值,如 Java Collection 类型 List、Set、Map 和 Properties,应该怎么做呢。

 示例如下:

这里是 JavaCollection.java 文件的内容:

public class JavaCollection {List addressList;Set  addressSet;Map  addressMap;Properties addressProp;public void setAddressList(List addressList) {this.addressList = addressList;}public List getAddressList() {System.out.println("List Elements :"  + addressList);return addressList;}public void setAddressSet(Set addressSet) {this.addressSet = addressSet;}public Set getAddressSet() {System.out.println("Set Elements :"  + addressSet);return addressSet;}public void setAddressMap(Map addressMap) {this.addressMap = addressMap;}  public Map getAddressMap() {System.out.println("Map Elements :"  + addressMap);return addressMap;}public void setAddressProp(Properties addressProp) {this.addressProp = addressProp;} public Properties getAddressProp() {System.out.println("Property Elements :"  + addressProp);return addressProp;}
}

主方法内容:

public class MainApp {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");JavaCollection jc=(JavaCollection)context.getBean("javaCollection");jc.getAddressList();jc.getAddressSet();jc.getAddressMap();jc.getAddressProp();}
}

Beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- Definition for javaCollection --><bean id="javaCollection" class="com.tutorialspoint.JavaCollection"><!-- results in a setAddressList(java.util.List) call --><property name="addressList"><list><value>INDIA</value><value>Pakistan</value><value>USA</value><value>USA</value></list></property><!-- results in a setAddressSet(java.util.Set) call --><property name="addressSet"><set><value>INDIA</value><value>Pakistan</value><value>USA</value><value>USA</value></set></property><!-- results in a setAddressMap(java.util.Map) call --><property name="addressMap"><map><entry key="1" value="INDIA"/><entry key="2" value="Pakistan"/><entry key="3" value="USA"/><entry key="4" value="USA"/></map></property><!-- results in a setAddressProp(java.util.Properties) call --><property name="addressProp"><props><prop key="one">INDIA</prop><prop key="two">Pakistan</prop><prop key="three">USA</prop><prop key="four">USA</prop></props></property></bean></beans>

上面注入的都是基本元素,如果集合中存储的是引用类型元素应该如何写Beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- Bean Definition to handle references and values --><bean id="..." class="..."><!-- Passing bean reference  for java.util.List --><property name="addressList"><list><ref bean="address1"/><ref bean="address2"/><value>Pakistan</value></list></property><!-- Passing bean reference  for java.util.Set --><property name="addressSet"><set><ref bean="address1"/><ref bean="address2"/><value>Pakistan</value></set></property><!-- Passing bean reference  for java.util.Map --><property name="addressMap"><map><entry key="one" value="INDIA"/><entry key ="two" value-ref="address1"/><entry key ="three" value-ref="address2"/></map></property></bean></beans>

 

 

 

 

 

 

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

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

相关文章

动态规划算法(背包问题)

1.应用场景-背包问题 背包问题:有一个背包,容量为4磅 ,现有如下物品1)要求达到的目标为装入的背包的总价值最大,并且重量不超出 2)要求装入的物品不能重复 2.动态规划算法介绍 1)动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步…

开启apache服务器gzip压缩

开启apache服务器gzip压缩-百度经验 https://jingyan.baidu.com/article/db55b609a7bc234ba20a2f7e.html 从服务端优化来说,通过对服务端做压缩配置可以大大减小文本文件的体积,从而使加载文本的速度成倍的加快。目前比较通用的压缩方法是启用gzip压缩。它会把浏览器请求的页…

Linux修改主机静态IP

通过VIM编辑器打开主机配置文件夹vim /etc/sysconfig/network-scripts/ifcfg-ens33修改IP地址为静态地址BOOTPROTO="static"添加静态IP地址和网关IP 地址 IPADDR=192.168.244.100 网关 GATEWAY=192.168.244.2 域名解析器 DNS1=192.168.244.2网络重启service network …

点击按钮收藏

分析 后台代码RouteServlet类:/*** 添加收藏* @param request* @param response* @throws ServletException* @throws IOException*/public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1、获取线…

前端5JQ

js获取用户输入 JS类属性操作 JS样式操作 事件 JS事件案例 JQuery类库 JQuery基本使用 基本筛选器(了解) 表单筛选器Js获取用户输入 普通数据(输入,选择) ​ 标签对象.value 获取文件数据的时候: 标签对象.value只能获取到文件路径,而标签对象.files结果是一个数组,可以通…

前端Day10

视口(viewport):浏览器显示页面内容的屏幕区域。分为布局视口、视觉视口、理想视口。 布局视口: 视觉视口: 理想视口: meta视口标签: width=device-width:布局视口宽度为当前设备宽度* user-scalable=no:不允许用户缩放 二倍图: 1.物理像素比: ①物理像素:即分辨…

分布式系统的session共享问题

目前大多数大型网站的服务器都采用了分布式服务集群的部署方式。所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。但是在服务集群中,session共享往往是一个比较头疼的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就…

网络network

网络network 基础network模型 OSI七层模型,一层一层封装数据帧(添加报文头),传过去之后再一层一层解封装(解封装掉报文头) 应用层:应用软件层面业务端口,例如http/https,ftp,sftp,smtp(25),除了在四层TCP IP+端口号的方式进行外,还需要检查http/https的url,cook…

python中的多线程与多进程

线程概念: 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一…

从设计到代码(第 3 天)

从设计到代码(第 3 天) 我最近正在开发一门课程,名为 三周内完成三个网页设计 .最初它是一个为期 3 周的研讨会材料,旨在成为一个包含许多实践的动手密集型研讨会。主要目标是教没有太多开发经验的人使用 HTML 和 CSS 来重现专业的设计模型——这就是为什么它被称为从设计到…

力扣507(java)-完美数(简单)

题目: 对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。 给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。示例 1: 输入:num = 28输出:true解释:28 = 1 + 2 + 4 + 7 + 141, 2, 4, 7和 14 是 28 的所有正因子。示例 …

仅Intel电脑可用:设计2D/3D文档绘图Autodesk AutoCAD 2021

Autodesk AutoCAD 2021是Mac上的二维和三维CAD设计软件,用于产品衍生式设计,创建设计方案,三维模型参数化,建模部件组织,创建制作清晰工程图,设计自动化配置等,AutoCAD 2021增强了针对草图的命令设计,简化流程,改进各种性能,转化探索更强大的设计。​编辑切换为居中 …

Echarts与ajax数据的动态交互

初学Echarts,Echarts的官网示例中配置项的数据需要用到js数组来传递数据,所以当我们从后端查询到数据后,往往需要通过ajax来进行数据交互。 这是官方示例的配置项。<script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = ech…

Openwrt 纯ipv6环境管理和上网

防火墙打开远程管理端口 添加端口如22或者使用ipv6端口转发到ipv4 使用socat opkg install socat图形化界面: drophair / luci-app-socatg wget -P /tmp https://github.com/big-tooth/luci-app-socatg/releases/download/v1.1/luci-app-socatg_1.1-1_all.ipk opkg install /tm…

c++ :虚拟机centos7+vscode

c++ :虚拟机centos7+vscodegcc、g++、make查看是否安装成功 $ gcc --version $ g++ --version $ make --version哪个没有,就yum install gcc-c++/yum install gcc/yum install make yum报错 "Failed to connect to 2001:da8:8000:6023::230: 网络不可达":参考链接…

最大正方形

问题:在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。 输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1"…

图解AspNetCore和Furion(1):应用启动

一、和AspNetCore5相比,从6开始,将Program和Startup类合并,直接在入口类中启动服务和中间件。同时,项目可以启动miniApi,直接在Program中设置路由和控制器。实际项目中,还是推荐使用控制器的方式。 二、Furion定义了静态类Serve,对AspNetCore的启动类进行了封装,同时支…

leetcode-172. 阶乘后的零

172. 阶乘后的零 图床:blogimg/刷题记录/leetcode/172/ 刷题代码汇总:https://www.cnblogs.com/geaming/p/16428234.html 题目思路 n!中有几个0与[1,n]中出现多少个5的因数有关。例如7! = 1234567出现了1次5,故最后末尾会出现1个0。26!中出现了5,10,15,20,25其中5的个数为1+…

java内部类

一、基本介绍 一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员 类的五大成员:属性、方法、构造器、代码块、内部类 内部类最大的特点就是可以直接访问私有属性,并且可以体现类…

redis主从数据同步原理

what:redis高可用:1、数据尽量不丢失;2、尽可能的提供服务;栗子:AOF 和 RDB 保证了数据持久化尽量不丢失;主从复制就是增加副本,一份数据保存到多个实例上。即使有一个实例宕机,其他实例依然可以持续服务;主从:复制——为单向的,即:只能从主复制到从;读写指责——…