1. 程式人生 > >Spring註解注入集合物件

Spring註解注入集合物件

目錄

1. @Autowired註解注入map、list與@Qualifier

package com.imooc.beanannotation.multibean;

public interface BeanInterface {
}
package com.imooc.beanannotation.multibean;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @order 註解可以調整注入順序,但只對list有效,對map無效。 
 *
 */
@Order(2)
@Component
public class BeanImplOne implements BeanInterface {
}
package com.imooc.beanannotation.multibean;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1)
@Component
public class BeanImplTwo implements BeanInterface {
}
package com.imooc.beanannotation.multibean;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class BeanInvoker {

    @Autowired
    private List<BeanInterface> list;

    /**
     * 對於向map中注入,bean注入後string為該bean的id。
    */
    @Autowired
    private Map<String, BeanInterface> map;

    /** @Autowired預設為by Type的  所以有兩個相同型別的bean  
     * 如果不使用 @Qualifier指定具體的bean就會丟擲異常
    */
    @Autowired
    @Qualifier("beanImplTwo")
    private BeanInterface beanInterface;

    public void say() {
        if (null != list && 0 != list.size()) {
            System.out.println("list...");
            for (BeanInterface bean : list) {
                System.out.println(bean.getClass().getName());
            }
        } else {
            System.out.println("List<BeanInterface> list is null !!!!!!!!!!");
        }

        System.out.println();

        if (null != map && 0 != map.size()) {
            System.out.println("map...");
            for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
                System.out.println(entry.getKey() + "      " + entry.getValue().getClass().getName());
            }
        } else {
            System.out.println("Map<String, BeanInterface> map is null !!!!!!!!!!");
        }

        System.out.println();
        if (null != beanInterface) {
            System.out.println(beanInterface.getClass().getName());
        } else {
            System.out.println("beanInterface is null...");
        }
    }
}

配置檔案:

<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" >
        
    <context:component-scan base-package="package com.imooc.beanannotation.multibean;"> 
    </context:component-scan>        
</beans>

測試類:

package com.Autowired.ListMap;
 
import org.junit.Test;
 
import com.imooc.test.base.UnitTestBase;
 
 
public class TestListMap  extends UnitTestBase{
    public TestListMap(){
    	super("classpath*:spring-beanannotation3.xml");
    }
    
    @Test
    public void test(){
    	BeanInvoke  bean=super.getBean("beanInvoke");
    	bean.say();
    }
}

結果:

2017-6-4 15:38:26 org.springframework.context.support.AbstractApplicationContext prepareRefresh
資訊: Refreshing org[email protected]58a17083: startup date [Sun Jun 04 15:38:26 CST 2017]; root of context hierarchy
2017-6-4 15:38:26 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from URL [file:/E:/myeclipse/workspace/Spring2/bin/spring-beanannotation3.xml]
2017-6-4 15:38:27 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
資訊: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
list...
2017-6-4 15:38:27 org.springframework.context.support.AbstractApplicationContext doClose
資訊: Closing org[email protected]58a17083: startup date [Sun Jun 04 15:38:26 CST 2017]; root of context hierarchy
com.Autowired.ListMap.BeanImplTwo
com.Autowired.ListMap.BeanImplOne
 
map...
beanImplOne    com.Autowired.ListMap.BeanImplOne
beanImplTwo    com.Autowired.ListMap.BeanImplTwo
-------------------------
com.Autowired.ListMap.BeanImplOne

以上是示例demo。當時看到這裡之後有些懵,全域性搜尋之後並沒有發現定義一個List和Map的物件。然而debug執行之後卻發現它們的確都有值。覺得很奇怪,最後在除錯List的時候突然靈感一閃,如果只有一個物件那麼List裡面的值不就只有一個嗎。於是開始測試驗證,結果發現的確如此。當例項化一個BeanInterface之後,另外一個類採用泛型注入List,Spring竟然成功的將例項化的物件放入List之中。思路開啟之後,針對Map的就更好說了。Spring會將service的名字作為key,物件作為value封裝進入Map。

2. Spring依賴注入IoC各種資料型別(list、map、set、陣列)

public class TestEntity {
    private List<String> list; // List型別
    private String[] array; // 陣列型別
    private Set<String> set; // Set型別
    private Map<String, String> map; // Map型別

    //為屬性新增set方法省略

    public void showValue() {
    System.out.println("List屬性:" + this.list);
    System.out.println("陣列屬性[0]:" + this.array[0]);
    System.out.println("Set屬性:" + this.set);
    System.out.println("Map屬性:" + this.map);
    }
}

配置檔案:(有一點需要注意:標籤中的name屬性值,必須和注入實體類中的屬性相同。)

<!-- 注入List型別 -->
    <property name="list">
        <list>
            <!-- 定義List中的元素 -->
            <!-- 直接用value標籤為list賦值 -->
            <value>足球</value>
            <value>籃球</value>
        </list>
    </property>
    <!-- 注入陣列型別 -->
    <property name="array">
        <list>
            <!-- 定義陣列中的元素 -->
            <value>足球</value>
            <value>籃球</value>
        </list>
    </property>
    <!-- 注入Set型別 -->
    <property name="set">
        <list>
            <!-- 定義Set中的元素 -->
            <value>足球</value>
            <value>籃球</value>
        </list>
    </property>
    <!--↑ list、陣列和set集合很像愛那個,賦值的方法沒有區別 ↑ -->

    <!-- 注入Map型別 -->
    <property name="map">
        <map>
            <!-- 定義Map中的鍵值對 -->
            <entry>
                <key>
                    <value>football</value>
                </key>
                <!-- ↑map集合中的鍵↑ -->
                <!-- 上下分別為鍵-值對應 -->
                <!-- ↓map集合中的鍵↓ -->
                <value>足球</value>
            </entry>
            <entry>
                <key>
                    <value>basketball</value>
                </key>
                <value>籃球</value>
            </entry>
        </map>
    </property>

執行結果如下:

List屬性:[足球, 籃球]
陣列屬性[0]:足球
Set屬性:[足球, 籃球]
Map屬性:{football=足球, basketball=籃球}

此外還有為類中的屬性注入Properties屬性、注入空字串、注入null值,在這裡簡要地說明一下:

像其他的型別一樣,定義屬性並新增set()方法、新增列印程式碼,便於我們觀察:

private Properties props; // Properties型別
private String emptyValue; // 注入空字串值
private String nullValue = "init value"; // 注入null值

System.out.println("Properties屬性:" + this.props);
System.out.println("注入空字串:[" + this.emptyValue + "]");
System.out.println("注入null值:" + this.nullValue);

做完這些工作以後,配置applicationContext.xml配置檔案:

<!-- 注入Properties型別 -->
    <property name="props">
        <props>
            <!-- 定義Properties中的鍵值對 -->
            <prop key="football">足球</prop>
            <prop key="basketball">籃球</prop>
        </props>
    </property>
    <!-- 注入空字串值 -->
    <property name="emptyValue">
        <!-- value標籤之前什麼也不寫,即為空字串 -->
        <value></value>
    </property>
    <!-- 注入null值 -->
    <property name="nullValue">
        <!-- null標籤 -->
        <null />
    </property>

這篇文章了。