Spring DI

一.   Spring DI 依赖注入

    利用spring IOC实例化了对象,而DI将实例化的对象注入到需要对象的地方,完成初始化任务。

    对象由spring创建,之后再由spring给属性赋值

    spring提供两种方式设置属性值:

        ① setter方法注入

        ②构造方法注入

二.   set方法注入

    2.1单值注入

        Cat有type和age属性,采用单值注入的方式,进行初始化。

 1 package com.hdu.setter;
 2 
 3 import java.io.Serializable;
 4 
 5 public class Cat implements Serializable{
 6     
 7     private static final long serialVersionUID = 1L;
 8     
 9     private String type;
10     private int age;
11     
12     public String getType() {
13         return type;
14     }
15     public void setType(String type) {
16         this.type = type;
17     }
18     public int getAge() {
19         return age;
20     }
21     public void setAge(int age) {
22         this.age = age;
23     }
24 }
Class Cat
<!-- 实例化Cat对象
     <bean>节点是用来告知spring实例化对象
     <property>节点,是用来告知spring对象有注入
     name="type" type->Type->setType
     把名字的第一个字母大写,前面用字符串连接一个set,构建出一个新字符串,
     拿着个字符串去class属性所对应的类中寻找是否有此方法签名的方法.
     如果有就反射调用此setter方法.setter方法的参数是value="smallCat"
-->
<bean id="cat" class="com.hdu.setter.Cat">
    <!-- 单值注入 -->
    <property name="type" value="smallCat"></property>
    <property name="age" value="3"></property>
</bean>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.setter.Cat;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_object.xml");
13         Cat cat = context.getBean("cat",Cat.class);
14         System.out.println(cat.getType()+" "+cat.getAge());
15     }
16 }

    2.2对象注入

        人人有猫。将Cat对象注入到Person对象中。

 1 package com.hdu.setter;
 2 
 3 public class Person {
 4     private String name;
 5     private int age;
 6     private Cat cat;
 7     public String getName() {
 8         return name;
 9     }
10     public void setName(String name) {
11         this.name = name;
12     }
13     public int getAge() {
14         return age;
15     }
16     public void setAge(int age) {
17         this.age = age;
18     }
19     public Cat getCat() {
20         return cat;
21     }
22     public void setCat(Cat cat) {
23         this.cat = cat;
24     }    
25 }
Class Person
<!-- 实例化Cat对象 -->
<bean id="cat" class="com.hdu.setter.Cat">
    <!-- 单值注入 -->
    <property name="type" value="smallCat"></property>
    <property name="age" value="3"></property>
</bean>
<!-- name="cat" cat->Cat->setCat
     ref="cat" 引用对象,cat是spring容器中的唯一id,指上面已经实例化的cat对象
-->
<bean id="person" class="com.hdu.setter.Person">
<!-- 单值注入 -->
<property name="name" value="kuotian"></property>
<property name="age" value="23"></property>
<!-- 对象注入 -->
<property name="cat" ref="cat"></property>
</bean>

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.setter.Person;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_object.xml");
13         //对象都是由spring创建和管理,对象的关系也要由spring来维护
14         Person person = context.getBean("person",Person.class);
15         System.out.println("Person:name="+person.getName());
16         System.out.println("Person:age="+person.getAge());
17         System.out.println("Person:Cat:type="+person.getCat().getType());
18         System.out.println("Person:Cat:age="+person.getCat().getAge());
19     }
20 }

    2.3集合注入

    toString是为了便于测试。

 1 package com.hdu.setter;
 2 
 3 import java.util.List;
 4 import java.util.Map;
 5 import java.util.Properties;
 6 import java.util.Set;
 7 
 8 public class Message {
 9     private List list;
10     private Set set;
11     private Map map;
12     private Properties pros;
13     public void setList(List list) {
14         this.list = list;
15     }
16     public void setSet(Set set) {
17         this.set = set;
18     }
19     public void setMap(Map map) {
20         this.map = map;
21     }
22     public void setPros(Properties pros) {
23         this.pros = pros;
24     }
25     @Override
26     public String toString() {
27         return "Message [list=" + list + ", set=" + set + ", map=" + map + ", pros=" + pros + "]";
28     }
29 }

        2.3.1直接注入

<!-- 实例化Cat对象 -->
<bean id="cat" class="com.hdu.setter.Cat">
    <!-- 单值注入 -->
    <property name="type" value="smallCat"></property>
    <property name="age" value="3"></property>
</bean>
    
<!-- 直接集合注入 -->
<bean id="message" class="com.hdu.setter.Message">
    <property name="list">
        <list>
            <!-- value引用的是单值 ref引用的事对象 -->
            <value>杭州</value>
            <value>17</value>
            <ref bean="cat" />
        </list>
    </property>
    <property name="set">
        <set>
            <value>杭州</value>
            <value>17</value>
            <ref bean="cat" />
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="bj" value="北京"></entry>
            <entry key="hz" value="杭州"></entry>
            <entry key="cc" value-ref="cat"></entry>
        </map>
    </property>
    <property name="pros">
        <props>
            <prop key="bj">北京</prop>
            <prop key="hz">杭州</prop>
            <prop key="sh">上海</prop>
        </props>
    </property>
</bean>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.setter.Message;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_collection.xml");
13         //直接注入
14         Message msg = context.getBean("message",Message.class);
15         System.out.println(msg);
16     }
17 }

        2.3.2间接注入

  间接注入,集合可复用多次。

  beans需要引入util命名空间。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 实例化Cat对象 -->
    <bean id="cat" class="com.hdu.setter.Cat">
        <!-- 单值注入 -->
        <property name="type" value="smallCat"></property>
        <property name="age" value="3"></property>
    </bean>
    <!-- 间接集合注入 -->
    <util:list id="list">
        <value>杭州</value>
        <value>17</value>
        <ref bean="cat" />
    </util:list>
    
    <util:set id="set">
        <value>杭州</value>
        <value>17</value>
        <ref bean="cat" />
    </util:set>
    
    <util:map id="map">
        <entry key="bj" value="北京"></entry>
        <entry key="hz" value="杭州"></entry>
        <entry key="cc" value-ref="cat"></entry>
    </util:map>
    
    <util:properties id="props">
        <prop key="bj">北京</prop>
        <prop key="hz">杭州</prop>
        <prop key="sh">上海</prop>
    </util:properties>
    
    <bean id="message1" class="com.hdu.setter.Message">
        <property name="list" ref="list"></property>
        <property name="set" ref="set"></property>
        <property name="map" ref="map"></property>
        <property name="pros" ref="props"></property>
    </bean>
</beans>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.setter.Message;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_collection.xml");
13         //直接注入
14         Message msg = context.getBean("message",Message.class);
15         System.out.println("直接注入:"+msg);
16         //间接注入
17         Message msg1 = context.getBean("message1",Message.class);
18         System.out.println("间接注入:"+msg1);
19     }
20 }

    从结果看出两种注入方式的效果是一样的。

    2.4表达式注入

        2.4.1 ${}表达式

            参考手册中的事例。

          

           

            ①准备一个properties文件。

jdbc_driverClass=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/tmpdb
jdbc_userName=root
jdbc_userPassword=root
mysql.properties

            ②存放数据相关类

 1 package com.hdu.util;
 2 
 3 public class JDBCUtil {
 4     private String driverClass;
 5     private String url;
 6     private String userName;
 7     private String password;
 8     public String getDriverClass() {
 9         return driverClass;
10     }
11     public void setDriverClass(String driverClass) {
12         this.driverClass = driverClass;
13     }
14     public String getUrl() {
15         return url;
16     }
17     public void setUrl(String url) {
18         this.url = url;
19     }
20     public String getUserName() {
21         return userName;
22     }
23     public void setUserName(String userName) {
24         this.userName = userName;
25     }
26     public String getPassword() {
27         return password;
28     }
29     public void setPassword(String password) {
30         this.password = password;
31     }
32     @Override
33     public String toString() {
34         return "JDBCUtil [driverClass=" + driverClass + ", url=" + url + ", userName=" + userName + ", password="
35                 + password + "]";
36     }
37 }
Class JDBCUtil

            ③xml中beans需要引入context命名空间。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
    <!-- 优先加载 先把属性文件加载到spring容器中 多个文件用逗号间隔 -->
    <context:property-placeholder location="classpath:resources/mysql.properties,resources/page.properties"/>
    <!-- 表达式注入 ${} -->
    <bean id="jdbcUtil" class="com.hdu.util.JDBCUtil">
        <property name="driverClass" value="${jdbc_driverClass}"></property>
        <property name="url" value="${jdbc_url}"></property>
        <property name="userName" value="${jdbc_userName}"></property>
        <property name="password" value="${jdbc_userPassword}"></property>
    </bean>
</beans>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.util.JDBCUtil;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_expression1.xml");
13         //从容器中取出对象
14         JDBCUtil jdbcUtil = context.getBean("jdbcUtil", JDBCUtil.class);
15         System.out.println(jdbcUtil);
16     }
17 }

结果:

         2.4.1 #{}表达式

        ③xml中beans需要引入util命名空间。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
    <!-- 优先加载 先把属性文件加载到spring容器中 多个文件用逗号间隔 -->
    <util:properties id="manyProperties" location="classpath:resources/mysql.properties,resources/page.properties"></util:properties>
    <!-- 表达式注入 #{} -->
    <bean id="jdbcUtil" class="com.hdu.util.JDBCUtil">
        <property name="driverClass" value="#{manyProperties.jdbc_driverClass}"></property>
        <property name="url" value="#{manyProperties.jdbc_url}"></property>
        <property name="userName" value="#{manyProperties.jdbc_userName}"></property>
        <property name="password" value="#{manyProperties.jdbc_userPassword}"></property>
    </bean>
    
</beans>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.util.JDBCUtil;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_expression2.xml");
13         JDBCUtil jdbcUtil = context.getBean("jdbcUtil", JDBCUtil.class);
14         System.out.println(jdbcUtil);
15     }
16 }

结果:

    2.5空值注入

        其中str2注入的是空值,而str1注入的只是空字符串。在测试方法中str1= str2=null的结果可以证明。

 1 package com.hdu.util;
 2 
 3 public class Kong {
 4     private String str1;
 5     private String str2;
 6     public String getStr1() {
 7         return str1;
 8     }
 9     public void setStr1(String str1) {
10         this.str1 = str1;
11     }
12     public String getStr2() {
13         return str2;
14     }
15     public void setStr2(String str2) {
16         this.str2 = str2;
17     }
18     @Override
19     public String toString() {
20         return "Kong [str1=" + str1 + ", str2=" + str2 + "]";
21     }
22 }

        str2才是注入空值。

<bean id="kong" class="com.hdu.util.Kong">
    <property name="str1" value=""></property>
    <property name="str2">
        <null></null>
    </property>
</bean>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.util.Kong;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_setter_kong.xml");
13         Kong kong = context.getBean("kong", Kong.class);
14         System.out.println(kong);
15     }
16 }

结果:

        其中str2注入的是空值,而str1注入的只是空字符串。在测试方法中str1= str2=null的结果可以证明。

三.构造方法注入

 1 package com.hdu.constructor;
 2 
 3 import com.hdu.setter.Cat;
 4 
 5 public class ConstructorDI {
 6     private int age;
 7     private Cat cat;
 8     private String name;
 9     public ConstructorDI() {
10         
11     }
12     
13     public ConstructorDI(int age, Cat cat, String name) {
14         super();
15         this.age = age;
16         this.cat = cat;
17         this.name = name;
18     }
19     
20     @Override
21     public String toString() {
22         return "ConstructorDI [age=" + age + ", cat=" + cat + ", name=" + name + "]";
23     }
24 }
<!-- 实例化Cat对象 -->
<bean id="cat" class="com.hdu.setter.Cat">
    <property name="type" value="smallCat"></property>
    <property name="age" value="3"></property>
</bean>
<!-- 
     index:从0开始,代表参数的位置
 -->
<bean id="constructor" class="com.hdu.constructor.ConstructorDI">
    <constructor-arg index="0" value="20"></constructor-arg>
    <constructor-arg index="1" ref="cat"></constructor-arg>
    <constructor-arg index="2" value="张三"></constructor-arg>
</bean>

测试

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.constructor.ConstructorDI;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_constructor.xml");
13         ConstructorDI constructor = context.getBean("constructor", ConstructorDI.class);
14         System.out.println(constructor);
15     }
16 }
原文地址:https://www.cnblogs.com/kuotian/p/8794245.html