基于XMl的DI
1.集合屬性注入
2.array數組屬性注入
3.List<>屬性注入
4.Set<>屬性注入
5.Map<K,V>屬性注入
6.Properties屬性注入
7.autowire自動注入
8.SPEL注入
School類
package Part02.collectionDI;
/**
* Created by futao on 2017/10/10.
*/
public class School {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
'}';
}
}
Some類
package Part02.collectionDI;
import java.util.*;
/**
* Created by futao on 2017/10/10.
*/
public class Some {
private School[] schools;
private List<String> myList;
private Set<String> mySet;
private Map<String,Object> myMap;
private Properties myPro;
public void setSchools(School[] schools) {
this.schools = schools;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, Object> myMap) {
this.myMap = myMap;
}
public void setMyPro(Properties myPro) {
this.myPro = myPro;
}
@Override
public String toString() {
return "Some{" +
"schools=" + Arrays.toString(schools) +
", myList=" + myList +
", mySet=" + mySet +
", myMap=" + myMap +
", myPro=" + myPro +
'}';
}
}
配置檔案applicationContextcollectionDI.xml
<?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 id="some" class="Part02.collectionDI.Some">
<!--數組-->
<property name="schools">
<array>
<ref bean="school1"/>
<ref bean="school2"/>
<ref bean="school2"/>
<ref bean="school2"/>
</array>
</property>
<!--list-->
<property name="myList">
<list>
<value>張三</value>
<value>李四</value>
<value>王五</value>
</list>
</property>
<!--這種方式myList的長度為1,value裡面的值會被當成一個值-->
<!--<property name="myList" value="張三,李四,王五"/>-->
<!--set-->
<property name="mySet">
<set>
<value>北京</value>
<value>上海</value>
<value>南昌</value>
</set>
</property>
<!--這種方式mySet的長度為1,value裡面的值會被當成一個值-->
<!--<property name="mySet" value="北京,上海,南昌"/>-->
<!--map-->
<property name="myMap">
<map>
<entry key="k1" value-ref="school1"/>
<entry key="k2" value-ref="school2"/>
<entry key="k3" value-ref="school2"/>
<entry key="k4" value-ref="school2"/>
<entry key="k5" value="wechat"/>
</map>
</property>
<property name="myPro">
<props>
<prop key="位址1">上海市</prop>
<prop key="位址2">闵行區</prop>
<prop key="位址3">吳泾鎮</prop>
<prop key="位址4">紫竹</prop>
<prop key="位址5">數位港</prop>
</props>
</property>
</bean>
<bean id="school1" class="Part02.collectionDI.School">
<property name="name" value="Ecjtu"></property>
</bean>
<bean id="school2" class="Part02.collectionDI.School">
<property name="name" value="NCDX"></property>
</bean>
</beans>
測試
/**
* 基于XML的DI-集合屬性注入
*/
@Test
fun test4collections(){
val classPathXmlApplicationContext = ClassPathXmlApplicationContext("applicationContextcollectionDI.xml")
val some = classPathXmlApplicationContext.getBean("some") as Some
println(GsonBuilder().setPrettyPrinting().create().toJson(some))
}
結果
{
"schools": [
{
"name": "Ecjtu"
},
{
"name": "NCDX"
},
{
"name": "NCDX"
},
{
"name": "NCDX"
}
],
"myList": [
"張三",
"李四",
"王二"
],
"mySet": [
"北京",
"上海",
"南昌"
],
"myMap": {
"k1": {
"name": "Ecjtu"
},
"k2": {
"name": "NCDX"
},
"k3": {
"name": "NCDX"
},
"k4": {
"name": "NCDX"
},
"k5": "wechat"
},
"myPro": {
"位址3": "吳泾鎮",
"位址2": "闵行區",
"位址1": "上海市",
"位址5": "數位港",
"位址4": "紫竹"
}
}
autowire自動裝配
package Part02.autoDIbyNameForDomain;
/**
* Created by futao on 2017/10/10.
*/
public class School {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
'}';
}
}
Student類
package Part02.autoDIbyNameForDomain;
/**
* Created by futao on 2017/10/10.
*/
public class Student {
private String name;
private int age;
private String address;
private School school;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public Student() {
}
public Student(String name, int age, String address, School school) {
this.name = name;
this.age = age;
this.address = address;
this.school = school;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", school=" + school +
'}';
}
}
applicationContext.xml
<?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 id="school1" class="Part02.autoDIbyNameForDomain.School">
<property name="name" value="上海交通大學"/>
</bean>
<bean id="student" class="Part02.autoDIbyNameForDomain.Student" autowire="byName">
<property name="age" value="18"/>
<property name="address" value="Shanghai"/>
</bean>
</beans>
/**
* 基于XML的DI-byName方式的域屬性自動注入
*/
@Test
fun test4autoDIbyNamefordomain() {
val classPathXmlApplicationContext = ClassPathXmlApplicationContext("applicationContextautoDIbyNameForDomain.xml")
val student = classPathXmlApplicationContext.getBean("student") as Part02.autoDIbyNameForDomain.Student
// serializeNulls()->為null的值也顯示出來,setPrettyPrinting()->格式化控制台輸出
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
println(student)
}
{
"name": null,
"age": 18,
"address": "Shanghai",
"school": null
}
Student{name='null', age=18, address='Shanghai', school=null}
others
在xml配置檔案中,autowire有5種類型,可以在<bean/>元素中使用autowire屬性指定
<table>
<tr>
<td>模式</td>
<td>說明</td>
</tr>
<td>no</td>
<td>不使用自動裝配,必須通過ref元素指定依賴,預設設定。</td>
<td>byName</td>
<td> 根據屬性名自動裝配。此選項将檢查容器并根據名字查找與屬性完全一緻的bean,并将其與屬性自動裝配。</td>
<td>byType</td>
<td> 如果容器中存在一個與指定屬性類型相同的bean,那麼将與該屬性自動裝配;如果存在多個該類型bean,那麼抛出異常,并指出不能使用byType方式進行自動裝配;如果沒有找到相比對的bean,則什麼事都不發生,也可以通過設定dependency-check="objects"讓Spring抛出異常。</td>
<td>constructor</td>
<td>與byType方式類似,不同之處在于它應用于構造器參數。如果容器中沒有找到與構造器參數類型一緻的bean,那麼抛出異常。</td>
<td>autodetect </td>
<td>通過bean類的自省機制(introspection)來決定是使用constructor還是byType方式進行自動裝配。如果發現預設的構造器,那麼将使用byType方式。 </td>
</table>
可以設定bean使自動裝配失效:
采用xml格式配置bean時,将
<bean/>
元素的autowire-candidate屬性設定為false,這樣容器在查找自動裝配對象時,将不考慮該bean,即它不會被考慮作為其它bean自動裝配的候選者,但是該bean本身還是可以使用自動裝配來注入其它bean的。
需要注意以下情況:
autowird="byType" (type->A)
B extends A
A是一個bean
如果此時B也是一個bean,則會報錯,該類型(A)的bean不止一個。
因為A a=new B()
B類型也可以作為A類型根據autowird="byType"進行注入
SPEL注入
Person類
package Part02.SPELDI;
/**
* Created by futao on 2017/10/11.
*/
public class Person {
/**
* 姓名
*/
private String pname;
/**
* 年齡
*/
private int page;
/**
* 帶參構造方法
*
* @param pname 姓名
* @param page 年齡
*/
public Person(String pname, int page) {
this.pname = pname;
this.page = page;
}
public Person() {
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
@Override
public String toString() {
return "Person{" +
"pname='" + pname + '\'' +
", page=" + page +
'}';
}
/**
* 控制年齡
*
* @return
*/
public int calculateAge() {
return page > 25 ? 25 : page;
}
}
package Part02.SPELDI;
/**
* Created by futao on 2017/10/12.
*/
public class Student {
private String sname;
private int sage;
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getSage() {
return sage;
}
public void setSage(int sage) {
this.sage = sage;
}
@Override
public String toString() {
return "Student{" +
"sname='" + sname + '\'' +
", sage=" + sage +
'}';
}
}
配置檔案
<?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 id="person" class="Part02.SPELDI.Person">
<property name="pname" value="老三"/>
<property name="page" value="#{T(java.lang.Math).random()*50}"/>
</bean>
<bean id="student" class="Part02.SPELDI.Student">
<property name="sname" value="#{person.pname}"/>
<!--<property name="sage" value="#{person.page > 25 ? 25:person.page}"/>-->
<property name="sage" value="#{person.calculateAge()}"/>
</bean>
</beans>
/**
* SPEL注入
*/
@Test
fun test4SPEL(){
val classPathXmlApplicationContext = ClassPathXmlApplicationContext("applicationContextSPEL.xml")
val student = classPathXmlApplicationContext.getBean("student") as Part02.SPELDI.Student
val person = classPathXmlApplicationContext.getBean("person") as Person
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(person))
student.sage=666
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(person))
person.page=999
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(person))
}
{
"sname": "老三",
"sage": 25
}
{
"pname": "老三",
"page": 29
}
{
"sname": "老三",
"sage": 666
}
{
"pname": "老三",
"page": 29
}
{
"sname": "老三",
"sage": 666
}
{
"pname": "老三",
"page": 999
}
tips:
如果一個類有帶參的構造函數,而沒有無參的構造函數,那麼在注冊bean的時候必須使用構造注入。