03-Spring基于xml的IOC配置--spring的依赖注入

1、概念

依赖注入:Dependency Injection(简称DI注入)。它是 spring 框架核心 ioc 的具体实现。 简单理解:可以在一个类中不通过new的方式依赖其它对象。目的是为了解耦。

 

PS:工程依旧沿用02课程的,maven和applicationContet.xml可以直接去02复制粘贴。

 

2、构造方法注入属性

2.1 创建Phone对象

public class Phone {

}

2.2 调整Student类。学生拥有姓名、年龄和手机。

public class Student {
    private String name;
    private Integer age;
    private Phone phone;

    public Student(String name, Integer age, Phone phone) {
        this.name = name;
        this.age = age;
        this.phone = phone;
        System.out.println("I'm " + name + ", age " + age + ", phone " + phone);
    }

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public void say() {
        System.out.println("I'm a Student");
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

2.3 修改applicationContext.xml文件装配Student的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">

    <!--
        1. spring会通过反射的方式创建对象,并将该对象以key和value的方式存入到IOC容器中。
        2. bean标签的id就是key,vaule就是类的全路径
        3. 通过bean标签将对象创建并存入到IOC容器中的方式,我们可以称之为装配bean
        4. 只要可以正常new出来的对象,都可以通过这种方式装配到IOC容器中
    -->
    <!-- 装配Phone对象到IOC容器中 -->
    <bean id="phone" class="com.demo.domain.Phone"/>

    <!-- 装配Studnt对象到IOC容器中 -->
    <bean id="student" class="com.demo.domain.Student">
        <!--
            constructor-arg标签:
                name属性:指定参数在构造函数中的名称,指定给谁赋值
                value属性:只能是基本数据类型和String类型的
                ref属性:指定其它bean类型,且必须在IOC容器中
        -->
        <constructor-arg name="name" value="zhangsan"/>
        <constructor-arg name="age" value="21"/>
        <constructor-arg name="phone" ref="phone"/>

    </bean>

    <!-- 使用静态工厂方法将Teacher对象装配到IOC容器中 -->
    <bean id="teacher" class="com.demo.factory.StaticFactory" factory-method="createTeacher"/>

    <!-- 使用实例工厂方法实例化bean -->
    <!-- 1. 装配实例工厂-->
    <bean id="instanceFactory" class="com.demo.factory.InstanceFactory"/>
    <!-- 2. 使用实例工厂创建cat对象-->
    <bean id="cat" factory-bean="instanceFactory" factory-method="createCat"/>

</beans>

2.4 运行方法

 

 

3、Setter方法注入

3.1 修改Teacher类

public class Teacher {

    private String name;

    private Integer age;

    private Phone phone;

    public Phone getPhone() {
        return phone;
    }

    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void say() {
        System.out.println("I'm a teacher. name: " + name + ", age: " + age + ", phone: " + phone);
    }
}

3.2 修改applicationContext.xml中装配Teacher对象的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">

    <!--
        1. spring会通过反射的方式创建对象,并将该对象以key和value的方式存入到IOC容器中。
        2. bean标签的id就是key,vaule就是类的全路径
        3. 通过bean标签将对象创建并存入到IOC容器中的方式,我们可以称之为装配bean
        4. 只要可以正常new出来的对象,都可以通过这种方式装配到IOC容器中
    -->
    <!-- 装配Phone对象到IOC容器中 -->
    <bean id="phone" class="com.demo.domain.Phone"/>

    <!-- 装配Studnt对象到IOC容器中 -->
    <bean id="student" class="com.demo.domain.Student">
        <!--
            constructor-arg标签:
                name属性:指定参数在构造函数中的名称,指定给谁赋值
                value属性:只能是基本数据类型和String类型的
                ref属性:指定其它bean类型,且必须在IOC容器中
        -->
        <constructor-arg name="name" value="zhangsan"/>
        <constructor-arg name="age" value="21"/>
        <constructor-arg name="phone" ref="phone"/>

    </bean>

    <!-- 使用静态工厂方法将Teacher对象装配到IOC容器中 -->
    <bean id="teacher" class="com.demo.factory.StaticFactory" factory-method="createTeacher">
        <!--
             property标签
                name属性:找的类中set方法后面的部分
                value属性:给属性赋值是基本数据类型和String类型的
                ref:给属性赋值是其他bean类型的。
         -->
        <property name="name" value="lisi"/>
        <property name="age" value="25"/>
        <property name="phone" ref="phone"/>
    </bean>

    <!-- 使用实例工厂方法实例化bean -->
    <!-- 1. 装配实例工厂-->
    <bean id="instanceFactory" class="com.demo.factory.InstanceFactory"/>
    <!-- 2. 使用实例工厂创建cat对象-->
    <bean id="cat" factory-bean="instanceFactory" factory-method="createCat"/>

</beans>

3.3 运行getTeaccherObjectFromSrpingIoc方法

 

 PS:我们看到打印了两句话。为什么?

  这是因为加载配置文件的时候,初始化对象装配到IOC容器中,由于Student对象是有参构造,并且在构造方法中打印了一句话。

4、P名称空间注入

4.1 在applicationContext.xml文件中添加P名称空间

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

 

 4.2 修改cat类


public class Cat {
private String name;
private Integer age;
private Phone phone;

public String getName() {
return name;
}

public Phone getPhone() {
return phone;
}

public void setPhone(Phone phone) {
this.phone = phone;
}

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

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public void say() {
System.out.println("I'm a cat. name: " + name + ", age: " + age + ", phone: " + phone);
}
}

4.3 修改applicationContext.xml文件中装配cat对象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"
       xmlns:p="http://www.springframework.org/schema/p">

    <!--
        1. spring会通过反射的方式创建对象,并将该对象以key和value的方式存入到IOC容器中。
        2. bean标签的id就是key,vaule就是类的全路径
        3. 通过bean标签将对象创建并存入到IOC容器中的方式,我们可以称之为装配bean
        4. 只要可以正常new出来的对象,都可以通过这种方式装配到IOC容器中
    -->
    <!-- 装配Phone对象到IOC容器中 -->
    <bean id="phone" class="com.demo.domain.Phone"/>

    <!-- 装配Studnt对象到IOC容器中 -->
    <bean id="student" class="com.demo.domain.Student">
        <!--
            constructor-arg标签:
                name属性:指定参数在构造函数中的名称,指定给谁赋值
                value属性:只能是基本数据类型和String类型的
                ref属性:指定其它bean类型,且必须在IOC容器中
        -->
        <constructor-arg name="name" value="zhangsan"/>
        <constructor-arg name="age" value="21"/>
        <constructor-arg name="phone" ref="phone"/>

    </bean>

    <!-- 使用静态工厂方法将Teacher对象装配到IOC容器中 -->
    <bean id="teacher" class="com.demo.factory.StaticFactory" factory-method="createTeacher">
        <!--
             property标签
                name属性:找的类中set方法后面的部分
                value属性:给属性赋值是基本数据类型和String类型的
                ref:给属性赋值是其他bean类型的。
         -->
        <property name="name" value="lisi"/>
        <property name="age" value="25"/>
        <property name="phone" ref="phone"/>
    </bean>

    <!-- 使用实例工厂方法实例化bean -->
    <!-- 1. 装配实例工厂-->
    <bean id="instanceFactory" class="com.demo.factory.InstanceFactory"/>
    <!-- 2. 使用实例工厂创建cat对象-->
    <bean id="cat" factory-bean="instanceFactory" factory-method="createCat" p:name="tom" p:age="21"
          p:phone-ref="phone"/>

</beans>

4.4 运行getCatObjectFromSrpingIoc方法

 

 

5、复杂类型的注入

5.1 创建HelloWorld实体类

import java.util.*;


public class HelloWorld {
    private String[] myArrays;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String, String> myMap;
    private Properties myProps;

    public String[] getMyArrays() {
        return myArrays;
    }

    public void setMyArrays(String[] myArrays) {
        this.myArrays = myArrays;
    }

    public List<String> getMyList() {
        return myList;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public Set<String> getMySet() {
        return mySet;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public Map<String, String> getMyMap() {
        return myMap;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public Properties getMyProps() {
        return myProps;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    public void sayHello() {
        System.out.println("Hello World!");
        System.out.println(Arrays.toString(myArrays));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
        System.out.println(myProps);

    }
}

5.2 在applicationContext.xml中装配HelloWorld对象

<?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"
       xmlns:p="http://www.springframework.org/schema/p">

    <!--
        1. spring会通过反射的方式创建对象,并将该对象以key和value的方式存入到IOC容器中。
        2. bean标签的id就是key,vaule就是类的全路径
        3. 通过bean标签将对象创建并存入到IOC容器中的方式,我们可以称之为装配bean
        4. 只要可以正常new出来的对象,都可以通过这种方式装配到IOC容器中
    -->
    <!-- 装配Phone对象到IOC容器中 -->
    <bean id="phone" class="com.demo.domain.Phone"/>

    <!-- 装配Studnt对象到IOC容器中 -->
    <bean id="student" class="com.demo.domain.Student">
        <!--
            constructor-arg标签:
                name属性:指定参数在构造函数中的名称,指定给谁赋值
                value属性:只能是基本数据类型和String类型的
                ref属性:指定其它bean类型,且必须在IOC容器中
        -->
        <constructor-arg name="name" value="zhangsan"/>
        <constructor-arg name="age" value="21"/>
        <constructor-arg name="phone" ref="phone"/>

    </bean>

    <!-- 使用静态工厂方法将Teacher对象装配到IOC容器中 -->
    <bean id="teacher" class="com.demo.factory.StaticFactory" factory-method="createTeacher">
        <!--
             property标签
                name属性:找的类中set方法后面的部分
                value属性:给属性赋值是基本数据类型和String类型的
                ref:给属性赋值是其他bean类型的。
         -->
        <property name="name" value="lisi"/>
        <property name="age" value="25"/>
        <property name="phone" ref="phone"/>
    </bean>

    <!-- 使用实例工厂方法实例化bean -->
    <!-- 1. 装配实例工厂-->
    <bean id="instanceFactory" class="com.demo.factory.InstanceFactory"/>
    <!-- 2. 使用实例工厂创建cat对象-->
    <bean id="cat" factory-bean="instanceFactory" factory-method="createCat" p:name="tom" p:age="21"
          p:phone-ref="phone"/>

    <!-- 装配HelloWorld对象到IOC容器中 -->
    <bean id="helloWorld" class="com.demo.domain.HelloWorld">
        <property name="myArrays">
            <array>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </array>
        </property>
        <property name="myList">
            <list>
                <value>CCC</value>
                <value>DDD</value>
                <value>EEE</value>
            </list>
        </property>
        <property name="mySet">
            <set>
                <value>FFF</value>
                <value>GGG</value>
                <value>HHH</value>
            </set>
        </property>
        <property name="myMap">
            <map>
                <entry key="name1" value="III"/>
                <entry key="name2" value="JJJ"/>
                <entry key="name3" value="KKK"/>
            </map>
        </property>
        <property name="myProps">
            <props>
                <prop key="name1">LLL</prop>
                <prop key="name2">MMM</prop>
                <prop key="name3">NNN</prop>
            </props>
        </property>
    </bean>
</beans>

5.3 测试

    @Test
    public void getHelloWorldObjectFromSrpingIoc() {
        //从SpringIOC容器中获取HelloWorld对象

        //1. 根据bean的id去IOC容器中获取HelloWorld对象
        HelloWorld helloWorld = (HelloWorld) ac.getBean("helloWorld");
        //2. 调用helloWolrd中的sayHello()方法
        helloWorld.sayHello();
    }

 

 

posted on 2019-11-15 14:13  yuanke  阅读(240)  评论(0编辑  收藏  举报