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

注入方式

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

参数名称注入

School实体类

packagecom.example.pojo03;
publicclassSchool{
    privateString name;
    privateString address;

  @Override
  publicString toString() {
    return"School{"+
      "name='"+ name +'\''+
          ", address='"+ address +'\''+
              '}';   
 }
publicSchool(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>

测试

packagecom.example.test;

importorg.junit.Test;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;

public classTestConstructor{
        //测试:通过构造方法的参数名称注入
        @Test
        publicvoidtestConstructorArgs(){
            //创建Spring容器
            ApplicationContext ac =newClassPathXmlApplicationContext("source03/applicationContext.xml");
            //取出School对象并打印输出
            System.out.printf("School实例对象: "+ ac.getBean("school"));
    }
}

测试结果

School有参构造方法执行,实例对象被创建....School实例对象: School{name='nefu', address='哈尔滨'}Process finished withexitcode0

参数下标注入

实体类:新增Student实体类,持有School实例对象的引用

packagecom.example.pojo03;
publicclassStudent{
        privateString name;
        privateint age;
        privateSchool school;

        @Override
        publicString toString() {
            return"Student{"+
                      "name='"+ name +'\''+
                      ", age="+ age +
                      ", school="+ school +
                      '}'; 
   }
publicStudent(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
      publicvoidtestConstructorIndex(){
          //创建Spring容器
          ApplicationContext ac =newClassPathXmlApplicationContext("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 withexitcode0

默认参数顺序注入

applicationContext.xml:新增bean标签,通过构造方法默认参数顺序注册Student实例对象,注意将之前对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 testConstructorDefaultOrder(){
                //创建Spring容器
                ApplicationContext ac =newClassPathXmlApplicationContext("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 withexitcode0

注意

前两种注入方式,由于一种依靠参数名和待注入值绑定,一种依靠参数下标和待注入值绑定,做到了注入值与待注入目标一一对应

所以注入标签顺序随意,调换 < 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
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容