Java開發學習(七)—-DI依賴注入之自動裝配與集合注入

一、自動配置

上一篇部落格花了大量的時間把Spring的注入去學習了下,總結起來就兩個字麻煩。麻煩在配置文件的編寫配置上。那有更簡單方式么?有,自動配置

1.1 依賴自動裝配

  • IoC容器根據bean所依賴的資源在容器中自動查找並注入到bean中的過程稱為自動裝配

1.2 自動裝配方式

  • 按類型(常用)

  • 按名稱

  • 按構造方法

  • 不啟用自動裝配

1.3 環境準備

  • 創建一個Maven項目

  • pom.xml添加依賴

  • resources下添加spring的配置文件

最終項目的結構如下:

(1)項目中添加BookDao、BookDaoImpl、BookService和BookServiceImpl類

public interface BookDao {
    public void save();
}
​
public class BookDaoImpl implements BookDao {
    
    private String databaseName;
    private int connectionNum;
    
    public void save() {
        System.out.println("book dao save ...");
    }
}
public interface BookService {
    public void save();
}
​
public class BookServiceImpl implements BookService{
    private BookDao bookDao;
​
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
​
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

(2)resources下提供spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="//www.springframework.org/schema/beans"
       xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

(3)編寫AppForAutoware運行類,載入Spring的IOC容器,並從中獲取對應的bean對象

public class AppForAutoware {
    public static void main( String[] args ) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}

1.4 完成自動裝配的配置

接下來,在上面這個環境中來完成自動裝配:

自動裝配只需要修改applicationContext.xml配置文件即可:

(1)將<property>標籤刪除

(2)在<bean>標籤中添加autowire屬性

首先來實現按照類型注入的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="//www.springframework.org/schema/beans"
       xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean class="com.itheima.dao.impl.BookDaoImpl"/>
    <!--autowire屬性:開啟自動裝配,通常使用按類型裝配-->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
​
</beans>

注意事項:

  • 需要注入屬性的類中對應屬性的setter方法不能省略

  • 被注入的對象必須要被Spring的IOC容器管理

  • 按照類型在Spring的IOC容器中如果找到多個對象,會報NoUniqueBeanDefinitionException

一個類型在IOC中有多個對象,還想要注入成功,這個時候就需要按照名稱注入,配置方式為:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="//www.springframework.org/schema/beans"
       xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean class="com.itheima.dao.impl.BookDaoImpl"/>
    <!--autowire屬性:開啟自動裝配,通常使用按類型裝配-->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byName"/>
​
</beans>

注意事項:

  • 按照名稱注入中的名稱指的是什麼?

    • bookDao是private修飾的,外部類無法直接方法

    • 外部類只能通過屬性的set方法進行訪問

    • 對外部類來說,setBookDao方法名,去掉set後首字母小寫是其屬性名

      • 為什麼是去掉set首字母小寫?

      • 這個規則是set方法生成的默認規則,set方法的生成是把屬性名首字母大寫前面加set形成的方法名

    • 所以按照名稱注入,其實是和對應的set方法有關,但是如果按照標準起名稱,屬性名和set對應的名是一致的

  • 如果按照名稱去找對應的bean對象,找不到則注入Null

  • 當某一個類型在IOC容器中有多個對象,按照名稱注入只找其指定名稱對應的bean對象,不會報錯

兩種方式介紹完後,以後用的更多的是按照類型注入。

最後對於依賴注入,需要注意一些其他的配置特徵:

  1. 自動裝配用於引用類型依賴注入,不能對簡單類型進行操作

  2. 使用按類型裝配時(byType)必須保障容器中相同類型的bean唯一,推薦使用

  3. 使用按名稱裝配時(byName)必須保障容器中具有指定名稱的bean,因變數名與配置耦合,不推薦使用

  4. 自動裝配優先順序低於setter注入與構造器注入,同時出現時自動裝配配置失效

二、集合注入

上一篇部落格我們已經能完成引入數據類型和簡單數據類型的注入,但是還有一種數據類型集合,集合中既可以裝簡單數據類型也可以裝引用數據類型,對於集合,在Spring中該如何注入呢?

常見的集合類型有如下幾種

  • 數組

  • List

  • Set

  • Map

  • Properties

針對不同的集合類型,該如何實現注入呢?

2.1 環境準備

  • 創建一個Maven項目

  • pom.xml添加依賴

  • resources下添加spring的配置文件applicationContext.xml

最終項目的結構如下:

(1)項目中添加添加BookDao、BookDaoImpl類

public interface BookDao {
    public void save();
}
​
public class BookDaoImpl implements BookDao {
    
public class BookDaoImpl implements BookDao {
​
    private int[] array;
​
    private List<String> list;
​
    private Set<String> set;
​
    private Map<String,String> map;
​
    private Properties properties;
​
     public void save() {
        System.out.println("book dao save ...");
​
        System.out.println("遍曆數組:" + Arrays.toString(array));
​
        System.out.println("遍歷List" + list);
​
        System.out.println("遍歷Set" + set);
​
        System.out.println("遍歷Map" + map);
​
        System.out.println("遍歷Properties" + properties);
    }
    //setter....方法省略,自己使用工具生成
}

(2)resources下提供spring的配置文件,applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="//www.springframework.org/schema/beans"
       xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>

(3)編寫AppForDICollection運行類,載入Spring的IOC容器,並從中獲取對應的bean對象

public class AppForDICollection {
    public static void main( String[] args ) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
    }
}

接下來,在上面這個環境中來完成集合注入:

下面的所以配置方式,都是在bookDao的bean標籤中使用<property>進行注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="//www.springframework.org/schema/beans"
       xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        
    </bean>
</beans>

2.2 注入數組類型

<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

2.3 注入List類型

<property name="list">
    <list>
        <value>itcast</value>
        <value>itheima</value>
        <value>boxuegu</value>
        <value>chuanzhihui</value>
    </list>
</property>

2.4 注入Set類型

<property name="set">
    <set>
        <value>itcast</value>
        <value>itheima</value>
        <value>boxuegu</value>
        <value>boxuegu</value>
    </set>
</property>

2.5 注入Map類型

<property name="map">
    <map>
        <entry key="country" value="china"/>
        <entry key="province" value="henan"/>
        <entry key="city" value="kaifeng"/>
    </map>
</property>

2.6 注入Properties類型

<property name="properties">
    <props>
        <prop key="country">china</prop>
        <prop key="province">henan</prop>
        <prop key="city">kaifeng</prop>
    </props>
</property>

配置完成後,運行下看結果:

說明:

  • property標籤表示setter方式注入,構造方式注入constructor-arg標籤內部也可以寫<array><list><set><map><props>標籤

  • List的底層也是通過數組實現的,所以<list><array>標籤是可以混用

  • 集合中要添加引用類型,只需要把<value>標籤改成<ref>標籤,這種方式用的比較少