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自动装配

School类

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>
<tr>
<td>no</td>
<td>不使用自动装配,必须通过ref元素指定依赖,默认设置。</td>
</tr>
<tr>
<td>byName</td>
<td> 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。</td>
</tr>
<tr>
<td>byType</td>
<td> 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生,也可以通过设置dependency-check="objects"让Spring抛出异常。</td>
</tr>
<tr>
<td>constructor</td>
<td>与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常。</td>
</tr>
<tr>
<td>autodetect </td>
<td>通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。 </td>
</tr>
</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;
    }
}

Student类

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的时候必须使用构造注入。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容