天天看點

Spring_DI_XML_02

歡迎移步部落格檢視-http://futaosmile.oschina.io/coder957

基于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的時候必須使用構造注入。