写点什么

【Spring 学习笔记 (三)】Spring Bean 属性注入

作者:倔强的牛角
  • 2022 年 6 月 04 日
  • 本文字数:2864 字

    阅读完需:约 9 分钟

【Spring 学习笔记(三)】Spring Bean 属性注入

写在前面😘

大一电子信息工程新生,请多多关照,希望能在 InfoQ 记录自己的学习历程!

【Spring 学习笔记】 系列教程基于 Spring 5.2.10.RELEASE讲解 ,部分图片来源于网络,侵权删。

属性注入概念

Spring 属性注入(DI依赖注入)有两种方式:setter 注入构造器注入

这个注入的属性可以是普通属性(基本数据类型与 String 等),也可以是一个引用数据类型(主要是对象),或者是一个集合(list、map、set 等)


  • 下表是属性注入 bean 标签中常用的元素👇


一、构造器注入

先来介绍下构造器注入:Spring 通过调用构造方法为成员变量赋值


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


  1. 在类中添加一个有参构造方法,构造方法内的每一个参数代表一个需要注入的属性;

  2. 在 Spring 的配置文件中定义 Bean;

  3. 在 <bean> 元素内使用 <constructor-arg> 元素,对构造函数内的属性进行赋值,Bean 的构造方法内有多少参数,就需要使用多少个 <constructor-arg> 元素。


下面通过示例介绍如何使用构造器注入

示例 1

  1. 创建员工类 Employee 和部门类 Dept,并添加有参构造方法(关键!)


/*员工类Employee*/public class Employee {    //员工编号    private String empNo;    //员工姓名    private String empName;    //部门信息    private Dept dept;    //有参构造方法    public Employee(String empNo, String empName, Dept dept) {        this.empNo = empNo;        this.empName = empName;        this.dept = dept;    }    ----省略toString方法------  }
/*部门类Dept*/public class Dept { //部门编号 private String deptNo; //部门名称 private String deptName; //有参构造方法 public Dept(String deptNo, String deptName) { this.deptNo = deptNo; this.deptName = deptName; } ----省略toString方法------}

复制代码


  1. 编写 spring 配置文件


<!--部门类属性注入--><bean id="dept" class="com.bighorn.pojo.Dept">    <constructor-arg index="0" value="1"/>    <constructor-arg index="1" value="后端组"/></bean><!--员工类属性注入--><bean id="employee" class="com.bighorn.pojo.Employee">    <constructor-arg index="0" value="1"/>    <constructor-arg index="1" value="bighorn"/>    <constructor-arg index="2" ref="dept"/></bean>
复制代码


  1. 编写运行程序


public static void main(String[] args) {    //获取IoC容器    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");    //从容器中获取对象    Employee employee = context.getBean("employee", Employee.class);    System.out.println(employee);}
复制代码


结果如下图👇


注意点

spring 识别有参构造方法的参数的三种形式:


  1. index 识别,案例一就是如此


<bean id="dept" class="com.bighorn.pojo.Dept">    <constructor-arg index="0" value="1"/>    <constructor-arg index="1" value="后端组"/></bean>
复制代码


  1. name 识别,如下


<bean id="dept" class="com.bighorn.pojo.Dept">    <constructor-arg name="deptNo" value="1"/>    <constructor-arg name="deptName" value="后端组"/></bean>
复制代码


  1. type 识别,如下


<bean id="dept" class="com.bighorn.pojo.Dept">    <constructor-arg type="int" value="1"/>    <constructor-arg type="java.lang.String" value="后端组"/></bean>
复制代码


三种形式各有各的好处和坏处。


以 type 识别不适合有多个参数类型相同的情况;以 index 形式识别,如果参数顺序变了又要重改;以 name 形式识别,如果参数名变了也要重改。总之,都不太利于解耦

二、setter 注入

下面来介绍下 setter 注入:Spring 通过调用 setter 方法为成员变量赋值。


https://xie.infoq.cn/article/03ab02726b92794c448696210提到过,在 Spring 实例化 Bean 时,IoC 容器会先调用默认构造方法实例化 Bean,然后通过反射机制调用这个 Bean 的 setXxx() 方法,将属性值注入到 Bean 中。


  • 使用 setter 注入实现属性注入大致步骤如下:


  1. 在 类中提供一个默认的无参构造方法(在没有带参构造方法的情况下,可省略),并为所有需要注入的属性提供一个 setter 方法

  2. 在 Spring 的 XML 配置文件中定义 Bean

  3. 使用 <property> 元素对各个属性进行赋值。


下面通过示例介绍如何使用 setter 注入方法

示例 2

  1. 创建员工类 Employee 和部门类 Dept,与示例一不同的是,需要添加各个成员变量的 setter 方法,也需要提供一个无参构造方法


/*员工类Employee*/public class Employee {    //员工编号    private String empNo;    //员工姓名    private String empName;    //部门信息    private Dept dept;    //无参构造方法,在没有其他带参构造方法的情况下,可以省略    public Employee() {    }       //各个属性的setter方法    public void setEmpNo(int empNo) {        this.empNo = empNo;    }    public void setEmpName(String empName) {        this.empName = empName;    }    public void setDept(Dept dept) {        this.dept = dept;    }    ----省略toString方法------  }
/*部门类Dept*/public class Dept { //部门编号 private String deptNo; //部门名称 private String deptName; //无参构造方法,在没有其他带参构造方法的情况下,可以省略 public Dept() { } //各个属性的setter方法 public void setDeptNo(int deptNo) { this.deptNo = deptNo; } public void setDeptName(String deptName) { this.deptName = deptName; } ----省略toString方法------}

复制代码


  1. 编写 spring 配置文件


<!--使用 property 元素完成属性注入        name: pojo类中的属性名称        value: 向属性注入的值      --><!--部门类属性注入--><bean id="dept" class="com.bighorn.pojo.Dept">    <property name="deptNo" value="2"/>    <property name="deptName" value="前端组"/></bean><!--员工类属性注入--><bean id="employee" class="com.bighorn.pojo.Employee">    <property name="empNo" value="114514"/>    <property name="empName" value="lzh"/>    <property name="dept" ref="dept"/></bean>

复制代码


  1. 编写运行程序


public static void main(String[] args) {    //获取IoC容器    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");    //从容器中获取对象    Employee employee = context.getBean("employee", Employee.class);    System.out.println(employee);}
复制代码


结果如下图👇


三、如何选择注入方式

  1. 如果对象在创建的过程中必须要注入指定的参数,则可以使用构造器注入行,因为使用 setter 注入有概率不进行注入导致 null 对象出现

  2. 如果对象在创建过程中注入的参数可有可无 ,则可以使用 setter 注入

  3. 常用的是setter注入方式,有必要时可以两者结合使用

写在后面🍻

感谢观看啦✨

有什么不足,欢迎指出哦💖

发布于: 刚刚阅读数: 3
用户头像

把学问造就,还期身健行优。 2022.06.02 加入

大一在读,电子信息工程专业。 希望在InfoQ写作社区记录自己的学习历程!

评论

发布
暂无评论
【Spring 学习笔记(三)】Spring Bean 属性注入_spring_倔强的牛角_InfoQ写作社区