Spring系列第七講 自動注入(autowire)詳解,高手在於堅持!

qwer1030274531發表於2020-10-30

手動注入的不足

上篇文章中介紹了依賴注入中的手動注入,所謂手動注入是指在xml中採用硬編碼的方式來配置注入的物件,比如透過構造器注入或者set方法注入,這些注入的方式都存在不足,比如下面程式碼:

public class A{
    private B b;
    private C c;
    private D d;
    private E e;
    ....
    private N n;
    //上面每個private屬性的get和set方法}12345678910

使用spring容器來管理,xml配置如下:

<bean class="b" class="B"/><bean class="c" class="C"/><bean class="d" class="D"/><bean class="e" class="E"/><bean class="a" class="A">
    <property name="b" ref="b"/>
    <property name="c" ref="c"/>
    <property name="d" ref="d"/>
    <property name="e" ref="e"/>
    ...</bean>1234567891011

上面的注入存在的問題:

  • 如果需要注入的物件比較多,比如A類中有幾十個屬性,那麼上面的property屬性是不是需要寫幾十個,此時配置檔案程式碼量暴增

  • 如果A類中新增或者刪除了一些依賴,還需要手動去調整bean xml中的依賴配置資訊,否則會報錯

  • 總的來說就是不利於維護和擴充套件

為了解決上面這些問題,spring為我們提供了更強大的功能:自動注入

在介紹自動注入之前需要先介紹一些基礎知識。

Class.isAssignableFrom方法

用法

isAssignableFrom是Class類中的一個方法,看一下這個方法的定義:

public native boolean isAssignableFrom(Class<?> cls)1

用法如下:

c1.isAssignableFrom(c2)1

用來判斷c2和c1是否相等,或者c2是否是c1的子類。

案例

@Testpublic void isAssignableFrom(){
    System.out.println(Object.class.isAssignableFrom(Integer.class)); //true
    System.out.println(Object.class.isAssignableFrom(int.class)); //false
    System.out.println(Object.class.isAssignableFrom(List.class)); //true
    System.out.println(Collection.class.isAssignableFrom(List.class)); //true
    System.out.println(List.class.isAssignableFrom(Collection.class)); //false}12345678

自動注入

自動注入是採用約定大約配置的方式來實現的,程式和spring容器之間約定好,遵守某一種都認同的規則,來實現自動注入。

xml中可以在bean元素中透過autowire屬性來設定自動注入的方式:

<bean id="" class="" autowire="byType|byName|constructor|default" />1
  • byteName:按照名稱進行注入

  • byType:按型別進行注入

  • constructor:按照構造方法進行注入

  • default:預設注入方式

下面我們詳解每種注入方式的用法。

按照名稱進行注入(byName)

用法

autowire設定為byName

<bean id="" class="X類" autowire="byName"/>1

spring容器會按照set屬性的名稱去容器中查詢同名的bean物件,然後將查詢到的物件透過set方法注入到對應的bean中,未找到對應名稱的bean物件則set方法不進行注入

需要注入的set屬性的名稱和被注入的bean的名稱必須一致。

來看看案例吧。

案例

DiByName.java

package com.javacode2018.lesson001.demo6;/**
 * 按照名稱自動注入
 */public class DiAutowireByName {
    public static class Service1 { //@1
        private String desc;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        @Override
        public String toString() {
            return "Service1{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }
    public static class Service2 { //@1
        private String desc;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        @Override
        public String toString() {
            return "Service2{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }
    private Service1 service1;//@3
    private Service2 service2;//@4
    public Service1 getService1() {
        return service1;
    }
    public void setService1(Service1 service1) {
        System.out.println("setService1->" + service1);
        this.service1 = service1;
    }
    public Service2 getService2() {
        return service2;
    }
    public void setService2(Service2 service2) {
        System.out.println("setService2->" + service2);
        this.service2 = service2;
    }
    @Override
    public String toString() {
        return "DiAutowireByName{" +
                "service1=" + service1 +
                ", service2=" + service2 +
                '}';
    }}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273

這個類中有2個屬性,名稱為:

  • service1

  • service2

這兩個屬性都有對應的set方法。

下面我們在bean xml中定義2個和這2個屬性同名的bean,然後使用按照名稱進行自動注入。

diAutowireByName.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="
       xmlns:xsi="
       xsi:schemaLocation="
    /spring-beans-4.3.xsd">
    <bean id="service1" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="service2" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service2">
        <property name="desc" value="service2"/>
    </bean>
    <bean id="service2-1" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service2">
        <property name="desc" value="service2-1"/>
    </bean>
    <!-- autowire:byName 配置按照name進行自動注入 -->
    <bean id="diAutowireByName1" class="com.javacode2018.lesson001.demo6.DiAutowireByName" autowire="byName"/>
    <!-- 當配置了自動注入,還可以使用手動的方式自動注入進行覆蓋,手動的優先順序更高一些 -->
    <bean id="diAutowireByName2" class="com.javacode2018.lesson001.demo6.DiAutowireByName" autowire="byName">
        <property name="service2" ref="service2-1"/>
    </bean></beans>12345678910111213141516171819202122232425

上面註釋認真看一下。

@1:定義了一個名稱為service1的bean

@2:定義了一個名稱為service2的bean

@3:定義diAutowireByName需要將autowire的值置為byName,表示按名稱進行自動注入。

spring容器建立diAutowireByName對應的bean時,會遍歷DiAutowireByName類中的所有set方法,然後得到set對應的屬性名稱列表:{“service1”,“service2”},然後遍歷這屬性列表,在容器中查詢和屬性同名的bean物件,然後呼叫屬性對應的set方法,將bean物件注入進去

測試用例

package com.javacode2018.lesson001.demo6;import com.javacode2018.lesson001.demo5.IocUtils;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.ArrayList;import java.util.Collection;import java.util.List;public class DiAutowireTest {
    /**
     * 按照名稱進行注入
     */
    @Test
    public void diAutowireByName() {
        String beanXml = "classpath:/com/javacode2018/lesson001/demo6/diAutowireByName.xml";
        ClassPathXmlApplicationContext context = IocUtils.context(beanXml);
        System.out.println(context.getBean("diAutowireByName"));
    }}12345678910111213141516171819202122

效果

執行diAutowireByName輸出:

setService1->Service1{desc='service1'}setService2->Service2{desc='service2'}setService2->Service2{desc='service2-1'}setService1->Service1{desc='service1'}DiAutowireByName{service1=Service1{desc='service1'}, service2=Service2{desc='service2'}}DiAutowireByName{service1=Service1{desc='service1'}, service2=Service2{desc='service2-1'}}123456

優缺點

按名稱進行注入的時候,要求名稱和set屬性的名稱必須同名,相對於硬編碼的方式注入,確實節省了不少程式碼。

按照型別進行自動注入

用法

autowire設定為byType

<bean id="" class="X類" autowire="byType"/>1

spring容器會遍歷x類中所有的set方法,會在容器中查詢和set引數型別相同的bean物件,將其透過set方法進行注入,未找到對應型別的bean物件則set方法不進行注入。

需要注入的set屬性的型別和被注入的bean的型別需要滿足isAssignableFrom關係。

按照型別自動裝配的時候,如果按照型別找到了多個符合條件的bean,系統會報錯。

set方法的引數如果是下面的型別或者下面型別的陣列的時候,這個set方法會被跳過注入:

Object,Boolean,boolean,Byte,byte,Character,char,Double,double,Float,float,Integer,int,Long,Short,shot,Enum,CharSequence,Number,Date,java.time.temporal.Temporal,java.net.URI,java.net.URI,java.util.Locale,java.lang.Class

來看看案例吧。

案例

DiByType.java

package com.javacode2018.lesson001.demo6;/**
 * 按照型別自動注入
 */public class DiAutowireByType {
    public static class Service1 {
        private String desc;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        @Override
        public String toString() {
            return "Service1{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }
    public static class Service2 {
        private String desc;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        @Override
        public String toString() {
            return "Service2{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }
    private Service1 service1;
    private Service2 service2;
    public Service1 getService1() {
        return service1;
    }
    public void setService1(Service1 service1) {
        System.out.println("setService1->" + service1); //@1
        this.service1 = service1;
    }
    public Service2 getService2() {
        return service2;
    }
    public void setService2(Service2 service2) {
        System.out.println("setService2->" + service2); //@2
        this.service2 = service2;
    }
    @Override
    public String toString() {
        return "DiByType{" +
                "service1=" + service1 +
                ", service2=" + service2 +
                '}';
    }}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273

DiAutowireByType類中有2個set方法分別來注入Service1和Service2,兩個set方法中都輸出了一行文字,一會執行的時候可以透過這個輸出可以看出set方法是否被呼叫了。

diAutowireByName.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="
       xmlns:xsi="
       xsi:schemaLocation="
    /spring-beans-4.3.xsd">
    <bean id="service1" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="service2" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service2">
        <property name="desc" value="service2"/>
    </bean>
    <bean id="service2-1" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service2">
        <property name="desc" value="service2-1"/>
    </bean>
    <!-- autowire:byName 配置按照name進行自動注入 -->
    <bean id="diAutowireByName1" class="com.javacode2018.lesson001.demo6.DiAutowireByName" autowire="byName"/>
    <!-- 當配置了自動注入,還可以使用手動的方式自動注入進行覆蓋,手動的優先順序更高一些 -->
    <bean id="diAutowireByName2" class="com.javacode2018.lesson001.demo6.DiAutowireByName" autowire="byName">
        <property name="service2" ref="service2-1"/>
    </bean></beans>12345678910111213141516171819202122232425

上面註釋認真看一下。

@1:定義了一個名稱為service1的bean

@2:定義了一個名稱為service2的bean

@3:定義diAutowireByName需要將autowire的值置為byName,表示按名稱進行自動注入。

spring容器建立diAutowireByName對應的bean時,會遍歷DiAutowireByName類中的所有set方法,然後得到set對應的屬性名稱列表:{“service1”,“service2”},然後遍歷這屬性列表,在容器中查詢和屬性同名的bean物件,然後呼叫屬性對應的set方法,將bean物件注入進去

測試用例

DiAutowireTest類中新增一個方法

/**
 * 按照set方法引數型別進行注入
 */@Testpublic void diAutowireByType() {
    String beanXml = "classpath:/com/javacode2018/lesson001/demo6/diAutowireByType.xml";
    ClassPathXmlApplicationContext context = IocUtils.context(beanXml);
    System.out.println(context.getBean("diAutowireByType1"));}123456789

效果

執行diAutowireByType輸出:

setService1->Service1{desc='service1'}setService2->Service2{desc='service2'}DiByType{service1=Service1{desc='service1'}, service2=Service2{desc='service2'}}123

優缺點

相對於手動注入,節省了不少程式碼,新增或者刪除屬性,只需要增減對應的set方法就可以了,更容易擴充套件了。

注入型別匹配的所有bean(重點)

按照型別注入還有2中比較牛逼的用法:

一個容器中滿足某種型別的bean可以有很多個,將容器中某種型別中的所有bean,透過set方法注入給一個java.util.List<需要注入的Bean的型別或者其父型別或者其介面>物件

將容器中某種型別中的所有bean,透過set方法注入給一個java.util.Map<String,需要注入的Bean的型別或者其父型別或者其介面>物件

來看個案例就懂了。

DiAutowireByTypeExtend.java

package com.javacode2018.lesson001.demo6;import java.util.List;import java.util.Map;/**
 * 滿足條件的bean注入到集合中(重點)
 */public class DiAutowireByTypeExtend {
    //定義了一個介面
    public interface IService1 {
    }
    public static class BaseServie {
        private String desc;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        @Override
        public String toString() {
            return "BaseServie{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }
    //Service1實現了IService1介面
    public static class Service1 extends BaseServie implements IService1 {
    }
    //Service1實現了IService1介面
    public static class Service2 extends BaseServie implements IService1 {
    }
    private List<IService1> serviceList;//@1
    private List<BaseServie> baseServieList;//@2
    private Map<String, IService1> service1Map;//@3
    private Map<String, BaseServie> baseServieMap;//@4
    public List<IService1> getServiceList() {
        return serviceList;
    }
    public void setServiceList(List<IService1> serviceList) {//@5
        this.serviceList = serviceList;
    }
    public List<BaseServie> getBaseServieList() {
        return baseServieList;
    }
    public void setBaseServieList(List<BaseServie> baseServieList) {//@6
        this.baseServieList = baseServieList;
    }
    public Map<String, IService1> getService1Map() {
        return service1Map;
    }
    public void setService1Map(Map<String, IService1> service1Map) {//@7
        this.service1Map = service1Map;
    }
    public Map<String, BaseServie> getBaseServieMap() {
        return baseServieMap;
    }
    public void setBaseServieMap(Map<String, BaseServie> baseServieMap) {//@8
        this.baseServieMap = baseServieMap;
    }
    @Override
    public String toString() { //9
        return "DiAutowireByTypeExtend{" +
                "serviceList=" + serviceList +
                ", baseServieList=" + baseServieList +
                ", service1Map=" + service1Map +
                ", baseServieMap=" + baseServieMap +
                '}';
    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889

@1,@2,@3,@4:定義了4個屬性,都是泛型型別的,都有對應的set方法。

@5:引數型別是List,這個集合集合中元素的型別是BaseServie,spring會找到容器中所有滿足BaseServie.isAssignableFrom(bean的型別)的bean列表,將其透過@5的set方法進行注入。

@6:同@5的程式碼

@7:這個引數型別是一個map了,map的key是string型別,value是IService1型別,spring容器會將所有滿足IService1型別的bean找到,按照name->bean物件這種方式丟到一個map中,然後呼叫@7的set方法進行注入,最後注入的這個map就是bean的名稱和bean物件進行對映的一個map物件。

@8:同@7的程式碼

@9:重寫了toString方法,輸出的時候好看一些

測試用例

DiAutowireTest新增一個方法:

/**
 * 按照型別注入集合
 */@Testpublic void diAutowireByTypeExtend() {
    String beanXml = "classpath:/com/javacode2018/lesson001/demo6/diAutowireByTypeExtend.xml";
    ClassPathXmlApplicationContext context = IocUtils.context(beanXml);
    //從容器中獲取DiAutowireByTypeExtend
    DiAutowireByTypeExtend diAutowireByTypeExtend = context.getBean(DiAutowireByTypeExtend.class);
    //輸出diAutowireByTypeExtend中的屬性看一下
    System.out.println("serviceList:" + diAutowireByTypeExtend.getServiceList());
    System.out.println("baseServieList:" + diAutowireByTypeExtend.getBaseServieList());
    System.out.println("service1Map:" + diAutowireByTypeExtend.getService1Map());
    System.out.println("baseServieMap:" + diAutowireByTypeExtend.getBaseServieMap());}123456789101112131415

效果

執行diAutowireByTypeExtend輸出:

serviceList:[BaseServie{desc='service1-1'}, BaseServie{desc='service1-2'}, BaseServie{desc='service2-1'}]baseServieList:[BaseServie{desc='service1-1'}, BaseServie{desc='service1-2'}, BaseServie{desc='service2-1'}]service1Map:{service1-1=BaseServie{desc='service1-1'}, service1-2=BaseServie{desc='service1-2'}, service2-1=BaseServie{desc='service2-1'}}baseServieMap:{service1-1=BaseServie{desc='service1-1'}, service1-2=BaseServie{desc='service1-2'}, service2-1=BaseServie{desc='service2-1'}}12345

下面我們來介紹另外一種自動注入方式。

按照建構函式進行自動注入

用法

autowire設定為constructor

<bean id="" class="X類" autowire="constructor"/>1

spring會找到x類中所有的構造方法(一個類可能有多個構造方法),然後將這些構造方法進行排序(先按修飾符進行排序,public的在前面,其他的在後面,如果修飾符一樣的,會按照建構函式引數數量倒敘,也就是採用貪婪的模式進行匹配,spring容器會盡量多注入一些需要的物件)得到一個建構函式列表,會輪詢這個構造器列表,判斷當前構造器所有引數是否在容器中都可以找到匹配的bean物件,如果可以找到就使用這個構造器進行注入,如果不能找到,那麼就會跳過這個構造器,繼續採用同樣的方式匹配下一個構造器,直到找到一個合適的為止。

來看看案例吧。

案例

DiAutowireByConstructor.java

package com.javacode2018.lesson001.demo6;/**
 * 建構函式的方式進行自動注入
 */public class DiAutowireByConstructor {
    public static class BaseServie {
        private String desc;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        @Override
        public String toString() {
            return "BaseServie{" +
                    "desc='" + desc + '\'' +
                    '}';
        }
    }
    //Service1實現了IService1介面
    public static class Service1 extends BaseServie {
    }
    //Service1實現了IService1介面
    public static class Service2 extends BaseServie {
    }
    private Service1 service1;
    private Service2 service2;
    public DiAutowireByConstructor() { //@0
    }
    public DiAutowireByConstructor(Service1 service1) { //@1
        System.out.println("DiAutowireByConstructor(Service1 service1)");
        this.service1 = service1;
    }
    public DiAutowireByConstructor(Service1 service1, Service2 service2) { //@2
        System.out.println("DiAutowireByConstructor(Service1 service1, Service2 service2)");
        this.service1 = service1;
        this.service2 = service2;
    }
    public Service1 getService1() {
        return service1;
    }
    public void setService1(Service1 service1) {
        this.service1 = service1;
    }
    public Service2 getService2() {
        return service2;
    }
    public void setService2(Service2 service2) {
        this.service2 = service2;
    }
    @Override
    public String toString() {
        return "DiAutowireByConstructor{" +
                "service1=" + service1 +
                ", service2=" + service2 +
                '}';
    }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475

@1:1個引數的建構函式

@2:2個引數的建構函式 /guiyang/

2個有參建構函式第一行都列印了一段文字,一會在輸出中可以看到程式碼是呼叫了那個建構函式建立物件。

diAutowireByConstructor.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="
       xmlns:xsi="
       xsi:schemaLocation="
    /spring-beans-4.3.xsd">
    <bean class="com.javacode2018.lesson001.demo6.DiAutowireByConstructor$Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="diAutowireByConstructor" class="com.javacode2018.lesson001.demo6.DiAutowireByConstructor"
          autowire="constructor"/></beans>1234567891011121314

測試用例

DiAutowireTest新增一個方法

/**
 * 建構函式的方式進行自動注入
 */@Testpublic void diAutowireByConstructor() {
    String beanXml = "classpath:/com/javacode2018/lesson001/demo6/diAutowireByConstructor.xml";
    ClassPathXmlApplicationContext context = IocUtils.context(beanXml);
    System.out.println(context.getBean("diAutowireByConstructor"));}123456789

效果

執行diAutowireByConstructor輸出:

DiAutowireByConstructor(Service1 service1)DiAutowireByConstructor{service1=BaseServie{desc='service1'}, service2=null}12

從輸出中可以看到呼叫的是DiAutowireByConstructor類中的第一個建構函式注入了service1 bean。

建構函式匹配採用貪婪匹配,多個建構函式結合容器找到一個合適的建構函式,最匹配的就是第一個有參建構函式,而第二個有參建構函式的第二個引數在spring容器中找不到匹配的bean物件,所以被跳過了。

我們在diAutowireByConstructor.xml加入Service2的配置: /epilepsy/

<bean class="com.javacode2018.lesson001.demo6.DiAutowireByConstructor$Service2">
    <property name="desc" value="service2"/></bean>123

再來執行一下diAutowireByConstructor輸出:

DiAutowireByConstructor(Service1 service1, Service2 service2)DiAutowireByConstructor{service1=BaseServie{desc='service1'}, service2=BaseServie{desc='service2'}}12

此時可以看到第二個有參建構函式被呼叫了,滿足了貪婪方式的注入原則,最大限度的注入所有依賴的物件。

autowire=default

用法

bean xml的根元素為beans,注意根元素有個default-autowire屬性,這個屬性可選值有(no|byName|byType|constructor|default),這個屬性可以批次設定當前檔案中所有bean的自動注入的方式,bean元素中如果省略了autowire屬性,那麼會取default-autowire的值作為其autowire的值,而每個bean元素還可以單獨設定自己的autowire覆蓋default-autowire的配置,如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="
       xmlns:xsi="
       xsi:schemaLocation="
    /spring-beans-4.3.xsd"       default-autowire="byName"></beans>12345678

案例

diAutowireByDefault.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="
       xmlns:xsi="
       xsi:schemaLocation="
    /spring-beans-4.3.xsd"       default-autowire="byName"> //@1
    <bean id="service1" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service1">
        <property name="desc" value="service1"/>
    </bean>
    <bean id="service2" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service2">
        <property name="desc" value="service2"/>
    </bean>
    <bean id="service2-1" class="com.javacode2018.lesson001.demo6.DiAutowireByName$Service2">
        <property name="desc" value="service2-1"/>
    </bean>
    <!-- autowire:default,會採用beans中的default-autowire指定的配置 -->
    <bean id="diAutowireByDefault1" class="com.javacode2018.lesson001.demo6.DiAutowireByName" autowire="default"/> //@2
    <!-- autowire:default,會採用beans中的default-autowire指定的配置,還可以使用手動的方式自動注入進行覆蓋,手動的優先順序更高一些 -->
    <bean id="diAutowireByDefault2" class="com.javacode2018.lesson001.demo6.DiAutowireByName" autowire="default"> //@3
        <property name="service2" ref="service2-1"/>
    </bean></beans>1234567891011121314151617181920212223242526

注意上面的@1配置的default-autowire=“byName”,表示全域性預設的自動注入方式是:按名稱注入

@2和@3的autowire=default,那麼注入方式會取default-autowire的值。

測試用例 /primary/

DiAutowireTest中新增一個方法

/**
 * autowire=default
 */@Testpublic void diAutowireByDefault() {
    String beanXml = "classpath:/com/javacode2018/lesson001/demo6/diAutowireByDefault.xml";
    ClassPathXmlApplicationContext context = IocUtils.context(beanXml);
    System.out.println(context.getBean("diAutowireByDefault1"));
    System.out.println(context.getBean("diAutowireByDefault2"));}12345678910

效果 /cure/

執行diAutowireByDefault輸出

setService1->Service1{desc='service1'}setService2->Service2{desc='service2'}setService2->Service2{desc='service2-1'}setService1->Service1{desc='service1'}DiAutowireByName{service1=Service1{desc='service1'}, service2=Service2{desc='service2'}}DiAutowireByName{service1=Service1{desc='service1'}, service2=Service2{desc='service2-1'}}123456

總結 /yunnan/

xml中手動注入存在的不足之處,可以透過自動注入的方式來解決,本文介紹了3中自動注入:透過名稱自動注入、透過型別自動注入、透過構造器自動注入

按型別注入中有個比較重要的是注入匹配型別所有的bean,可以將某種型別所有的bean注入給一個List物件,可以將某種型別的所有bean按照 bean名稱->bean物件的對映方式注入給一個Map物件,這種用法比較重要,用途比較大,要掌握

spring中還有其他自動注入的方式,用起來會更爽,後面的文章中我們會詳細介紹。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30239065/viewspace-2731171/,如需轉載,請註明出處,否則將追究法律責任。

相關文章