Spring依赖注入基于XML的 DI

Posted 花伤情犹在

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring依赖注入基于XML的 DI相关的知识,希望对你有一定的参考价值。

DI:给属性赋值

spring调用类的无参数构造方法,创建对象。 对象创建后给属性赋值。

给属性赋值可以使用 :

  1. xml配置文件中的标签和属性
  2. 使用注解

DI分类:

  1. set注入,也叫做设值注入
  2. 构造注入

set注入

public class Student {
	//姓名
    private String name;
    //年龄
    private int age;
	//无参构造器
    public Student() {
        System.out.println("Student无参数构造方法");
    }

    public void setName(String name) {
        System.out.println("setName==="+name);
        this.name = "Hello:"+name;
    }

    public void setAge(int age) {
        System.out.println("setAge=="+age);
        this.age = age;
    }

    public void setEmail(String email){
        //email属性  <property name="email" value="lisi@qq.com" />
        System.out.println("setEmail==="+email);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '}';
    }
}

定义一个Student类:
定义属性:name和age
生成它们的set方法
注意:上面没有定义属性email,只生成set方法(setEmail)
重写toString方法

定义applicationContext配置文件:

set注入

property用来绑定属性:name为要绑定的属性名称

set注入分为2种类型:普通类型和引用类型。

普通类型:java中的基本数据类型和String。
引用类型:除了基本数据类型其它都是引用类型(这里除了`String`)

普通类型赋值使用value=""
引用类型赋值使用ref=""

普通类型set注入

配置文件:

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--声明bean-->
    
    <!--普通类型set注入-->
    <bean id="myStudent" class="com.bjpowernode.ba01.Student">
        <property name="name" value="李四"/><!--setName("李四")-->
        <property name="age" value="22" /><!--setAge(22)-->
        <property name="email" value="lisi@qq.com" /><!--setEmail("xxx)-->
    </bean>

    <!--声明日期类-->
    <!--这里绑定了time属性,会调用setTime()方法
	Java Date类的setTime()方法设置日期对象。它将日期对象设置为代表格林尼治标准时间1970年1月1日00:00:00之后的时间毫秒。
	用法:
	public void setTime(long time)
	参数:该函数接受单个参数时间,该时间指定毫秒数。
	-->
    <bean id="mydate" class="java.util.Date">
        <property name="time" value="933295249276"/><!--setTime()-->
    </bean>
</beans>

普通类型set注入语法:

set注入: spring调用类的set方法,通过set方法完成属性赋值
          简单类型的set注入:
          语法: <bean id="xxx" class="yyy">
                   <property name="属性名" value="简单类型属性值"/>
                   ...
                </bean>

定义测试类:

public class MyTest01 {

    @Test
    public void test01(){
    	//指定配置文件的名称和路径
        String config="applicationContext.xml";
        //获取spring容器对象
        ApplicationContext ctx  = new ClassPathXmlApplicationContext(config);
		//从容器中获取student自定义对象
        Student student = (Student) ctx.getBean("myStudent");
		//调用student的toString方法
        System.out.println("student="+student);
		//从容器中获取java提供的日期对象Date
        Date date = (Date) ctx.getBean("mydate");
        //打印日期
        System.out.println("date==="+date);
    }
}

分析打印顺序:

  1. 首先spring是通过调用类的无参构造器创建对象的,所以第一次打印的是Student类的无法构造方法
  2. 然后spring在进行set注入时,会调用属性对应的set方法,在调用的时候会把你的属性名首字母变为大写(如果属性首字母原本就是大写即字母不变),然后在前面加上set,这样就调用到属性对应的set方法。由于setName()和setAge()都是在做属性赋值和打印操作,setEmail()方法中只是做了打印操作,因为没有定义属性email,所以顺序2是做了setName、setEmail()、setEmail()中的打印操作
  3. 在测试类中打印了student对象,由于重写了toString方法,所以会调用student中的toString方法,做打印信息操作
  4. 最后是在测试类中打印了Date对象,由于Date对象的toString方法也被重写了,返回的是时间信息,所以最后一步打印的是时间信息

运行测试:

引用类型set注入

定义一个School类:
定义属性:普通类型name和address
生成它们的set方法
重写toString方法

public class School {

    private String name;
    private String address;

    public void setName(String name) {
        this.name = name;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\\'' +
                ", address='" + address + '\\'' +
                '}';
    }
}

定义一个Student类:
定义属性:普通类型name和age,引用类型school
生成它们的set方法
注意:上面没有定义属性email,只生成set方法(setEmail)
重写toString方法

public class Student {

    private String name;
    private int age;
    //引用类型
    private School school;


    public Student() {
        System.out.println("Student无参数构造方法");
    }


    public void setName(String name) {
        System.out.println("setName==="+name);
        this.name = "Hello:"+name;
    }


    public void setAge(int age) {
        System.out.println("setAge=="+age);
        this.age = age;
    }

    public void setSchool(School school) {
        System.out.println("setSchool="+school);
        this.school = school;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

配置文件

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!--声明School-->
    <bean id="mySchool" class="com.bjpowernode.ba02.School">
        <property name="name" value="北京大学"/>
        <property name="address" value="北京的海淀区"/>
    </bean>

    <!--引用类型set注入-->
    <bean id="myStudent" class="com.bjpowernode.ba02.Student">
        <property name="name" value="李四"/>
        <property name="age" value="22" />
        <!--引用类型的赋值-->
        <property name="school" ref="mySchool" /><!--setSchool(mySchool)-->
    </bean>
    
</beans>

引用数据类型set注入语法:

set注入:
          引用类型set注入:
          语法:<bean id="xxx" class="yyy">
                   <property name="属性名" ref="bean的id"/>
                   ...
                </bean>

定义测试类:

public class MyTest2(){
	@Test
    public void test01(){

        Student student = new Student();
        student.setName("lisi");
        student.setAge(20);

        School school = new School();
        school.setName("北京大学");
        school.setAddress("北京海淀区");

        student.setSchool(school);
    }

}

测试类:

  1. spring通过无参构造方法创建对象所以会走所有的无参构造器
  2. 由于student中的setName和setAge中有打印操作所以会打印姓名和年龄
  3. 最后打印了school对象,然后调用了toString方法,school对象也重写了toString方法,所以会打印school的属性name和address

运行结果:

构造注入

构造注入: Spring调用类的有参数构造方法,创建对象同时给属性赋值

语法:
    <bean id="xxx" class="yyy">
       <constructor-arg>: 表示一个构造方法的形参
       标签有属性: name :构造方法形参名
                   index:构造方法的参数位置
                   value:简单类型的形参值
                   ref:  引用类型的形参值

    </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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--声明bean-->
    <!--
        构造注入: Spring调用类的有参数构造方法,创建对象同时给属性赋值
        语法:
            <bean id="xxx" class="yyy">
               <constructor-arg>: 表示一个构造方法的形参
               标签有属性: name :构造方法形参名
                           index:构造方法的参数位置
                           value:简单类型的形参值
                           ref:  引用类型的形参值

            </bean>
    -->


    <!--构造注入,使用name属性-->
    <bean id="myStudent" class="com.bjpowernode.ba03.Student">
        <constructor-arg name="myage" value="22" />
        <constructor-arg name="myname" value="李四"/>
        <constructor-arg name="mySchool" ref="mySchool"/>
    </bean>

    <!--构造注入,使用index,参数的位置,构造方法参数从左往右位置是0,1,2-->
    <bean id="myStudent2" class="com.bjpowernode.ba03.Student">
        <constructor-arg index="1" value="28"/>
        <constructor-arg index="0" value="张三"/>
        <constructor-arg index="2" ref="mySchool" />
    </bean>


    <!--构造注入,省略index属性-->
    <bean id="myStudent3" class="com.bjpowernode.ba03.Student">
        <constructor-arg  value="张峰"/>
        <constructor-arg  value="28"/>
        <constructor-arg  ref="mySchool" />
    </bean>

    <!--声明School-->
    <bean id="mySchool" class="com.bjpowernode.ba03.School">
        <property name="name" value="北京大学"/>
        <property name="address" value="北京的海淀区"/>
    </bean>

    <!--声明File对象-->
    <bean id="myFile" class="java.io.File">
        <constructor-arg name="parent" value="D:\\\\course"/>
        <constructor-arg name="child" value="2009班级网盘.txt" />
    </bean>

</beans>

引用类型自动注入

引用类型自动注入: spring根据byName,byType规则给引用类型赋值

byName注入:

 1.byName(按名称注入):java类中引用类型的属性名称和spring容器中bean的id名称一样,且数据类型一样的, 这样的bean能够赋值给引用类型。
      语法:
       <bean id="xxx" class="yy" autowire="byName">
          简单类型属性赋值
       </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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--声明bean-->
    <!-- byName 自动注入 -->
    <bean id="myStudent" class="com.bjpowernode.ba04.Student" autowire="byName">
        <property name="name" value="李四"/>
        <property name="age" value="22" />
        <!--引用类型的赋值-->
        <!--<property name="school" ref="mySchool" />-->
    </bean>

    <!--声明School-->
    <bean id="school" class="com.bjpowernode.ba04.School">
        <property name="name" value="清华大学"/>
        <property name="address" value="北京的海淀区"/>
    </bean>

</beans>

byType注入:

2.byType(按类型注入):java类中引用类型的数据类型和bean的class是同源的,
                              这些的bean能够赋值给引用类型。

          同源关系:
           1. java中引用类型的数据类型和bean的class值是一样的。
           2. java中引用类型的数据类型和bean的class值是父子类关系的。
           3. java中引用类型的数据类型和bean的class值是接口和实现类关系的。

           语法:
           <bean id="xxx" class="yy" autowire="byType">
              简单类型属性赋值
           </bean>

           注意: 在xml配置文件中, 符合条件的对象,只能有一个。
                 多余一个是报错的。

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi以上是关于Spring依赖注入基于XML的 DI的主要内容,如果未能解决你的问题,请参考以下文章

基于 Spring 注释的 DI 与 xml 配置?

手写Spring的IOC容器和DI依赖注入

Spring_IOC控制反转和DI依赖注入

Spring 3.0 学习-DI 依赖注入_创建Spring 配置-使用一个或多个XML 文件作为配置文件,使用自动注入(byName),在代码中使用注解代替自动注入,使用自动扫描代替xml中bea(

Spring 依赖注入(DI)详解 [Spring][依赖注入的 6 种实现方式][setter注入][构造器注入][注解注入][自动装配注入][静态工厂注入][实例工厂注入]

Spring