Spring 03: 基于xml的构造方法注入

注入方式

  • 具体有3种注入方式:通过构造方法的 a.参数名称注入 b.参数下标注入 c.默认参数顺序注入

参数名称注入

  • School实体类
package com.example.pojo03;  public class School {     private String name;     private String address;      @Override     public String toString() {         return "School{" +                 "name='" + name + '/'' +                 ", address='" + address + '/'' +                 '}';     }      public School(String name, String address) {         this.name = name;         this.address = address;         System.out.println("School有参构造方法执行,实例对象被创建....");     } } 
  • applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>  <!-- bean工厂 --> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">       <!-- 通过构造方法的参数名称,注册School实例对象 -->     <bean id="school" class="com.example.pojo03.School">         <constructor-arg name="name" value="nefu"/>         <constructor-arg name="address" value="哈尔滨"/>     </bean>      </beans> 
  • 测试
package com.example.test;  import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestConstructor {      //测试:通过构造方法的参数名称注入     @Test     public void testConstructorArgs(){         //创建Spring容器         ApplicationContext ac = new ClassPathXmlApplicationContext("source03/applicationContext.xml");         //取出School对象并打印输出         System.out.printf("School实例对象: " + ac.getBean("school"));     } } 
  • 测试结果
School有参构造方法执行,实例对象被创建.... School实例对象: School{name='nefu', address='哈尔滨'}  Process finished with exit code 0 

参数下标注入

  • 实体类:新增Student实体类,持有School实例对象的引用
package com.example.pojo03;  public class Student {     private String name;     private int age;     private School school;      @Override     public String toString() {         return "Student{" +                 "name='" + name + '/'' +                 ", age=" + age +                 ", school=" + school +                 '}';     }      public Student(String name, int age, School school) {         this.name = name;         this.age = age;         this.school = school;         System.out.println("Student有参构造方法执行,实例对象被创建....");     } } 
  • applicationContext.xml:新增bean标签,注册Student实例对象
    <!-- 通过构造方法的参数下标,注册Student实例对象 -->     <bean id="student" class="com.example.pojo03.Student">         <constructor-arg index="0" value="荷包蛋"/>         <constructor-arg index="1" value="20"/>         <constructor-arg index="2" ref="school"/>     </bean> 
  • 测试:新增测试方法
    //测试:通过构造方法的参数下标注入     @Test     public void testConstructorIndex(){         //创建Spring容器         ApplicationContext ac = new ClassPathXmlApplicationContext("source03/applicationContext.xml");         //取出Student对象并打印输出         System.out.printf("Student实例对象: " + ac.getBean("student"));     } 
  • 测试结果
School有参构造方法执行,实例对象被创建.... Student有参构造方法执行,实例对象被创建.... Student实例对象: Student{name='荷包蛋', age=20, school=School{name='nefu', address='哈尔滨'}}  Process finished with exit code 0 

默认参数顺序注入

  • applicationContext.xml:新增bean标签,通过构造方法默认参数顺序注册Student实例对象,注意将之前对Student实例对象的注册先注释掉
    <!-- 通过构造方法默认参数顺序,注册Student实例对象 -->     <bean id="student02" class="com.example.pojo03.Student">         <constructor-arg value="荷包蛋"/>         <constructor-arg value="20"/>         <constructor-arg ref="school"/>     </bean> 
  • 测试:新增测试方法
    //测试:通过构造方法默认参数顺序注入     @Test     public void testConstructorDefaultOrder(){         //创建Spring容器         ApplicationContext ac = new ClassPathXmlApplicationContext("source03/applicationContext.xml");         //取出Student对象并打印输出         System.out.printf("Student实例对象: " + ac.getBean("student02"));     } 
  • 测试结果
School有参构造方法执行,实例对象被创建.... Student有参构造方法执行,实例对象被创建.... Student实例对象: Student{name='荷包蛋', age=20, school=School{name='nefu', address='哈尔滨'}}  Process finished with exit code 0 

注意

前两种注入方式,由于一种依靠参数名和待注入值绑定,一种依靠参数下标和待注入值绑定,做到了注入值与待注入目标一一对应
所以注入标签顺序随意,调换 < constructor-arg />标签的前后顺序,仍可正确注入数据

    <!-- 通过构造方法的参数下标,注册Student实例对象 -->     <bean id="student" class="com.example.pojo03.Student">         <constructor-arg index="0" value="荷包蛋"/>         <constructor-arg index="2" ref="school"/>         <constructor-arg index="1" value="20"/>     </bean> 
  • 但是依靠参数默认顺序注入时,要严格参考实体类中待注入属性的顺序和类型,保证与标签中的待注入值的类型相同,不然会类型解析错误,数据注入失败
    <!-- 通过构造方法默认参数顺序,注册Student实例对象 -->     <bean id="student02" class="com.example.pojo03.Student">         <constructor-arg value="荷包蛋"/>         <constructor-arg ref="school"/>         <constructor-arg value="20"/>     </bean> 
  • 容器启动时,School实例对象成功创建并注入数据,但创建Student对象时,待注入数据类型和目标属性类型不对应,类型解析错误,创建失败

image

商匡云商
Logo
注册新帐户
对比商品
  • 合计 (0)
对比
0
购物车