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對象,不會報錯
兩種方式介紹完後,以後用的更多的是按照類型注入。
最後對於依賴注入,需要注意一些其他的配置特徵:
-
自動裝配用於引用類型依賴注入,不能對簡單類型進行操作
-
使用按類型裝配時(byType)必須保障容器中相同類型的bean唯一,推薦使用
-
使用按名稱裝配時(byName)必須保障容器中具有指定名稱的bean,因變數名與配置耦合,不推薦使用
-
自動裝配優先順序低於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>