一. Spring DI 依賴注入java
利用spring IOC實例化了對象,而DI將實例化的對象注入到須要對象的地方,完成初始化任務。mysql
對象由spring建立,以後再由spring給屬性賦值spring
spring提供兩種方式設置屬性值:sql
① setter方法注入express
②構造方法注入spring-mvc
二. set方法注入mvc
2.1單值注入ide
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 }
<!-- 實例化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>
測試this
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 }
<!-- 實例化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
②存放數據相關類
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 }
③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 }