回顧
前幾篇我們介紹各種依賴依賴注入,都是顯式指定的,配置明確但同時也有些繁雜和重復,"很多發明的出發點,都是為了偷懶,懶人是推動社會進步的原動力",Spring 提供了自動注入依賴的機制,
本文內容
-
什么是自動依賴注入,有什么優點
-
autowire如何使用 -
autowire-candidate和primary配合自動裝配
什么是自動依賴注入,有什么優點
Spring 容器可以自動裝配依賴 bean 之間的關系, Spring 通過檢查 ApplicationContext 容器中的內容自動決議依賴 bean (也就是其它 bean),
優點如下:
- 自動裝配可以顯著減少指定屬性或建構式引數的需要(偷懶使用),
- 自動裝配可以隨著物件的發展而更新配置,例如,如果需要向類添加依賴項,則無需修改配置即可自動滿足該依賴項,因此,自動裝配在開發程序中特別有用,
缺點如下:
-
property和constructor-arg設定中的顯式依賴項總是會覆寫自動裝配,不能自動裝配簡單的屬性,如原語、字串和類(以及此類簡單屬性的陣列), -
自動裝配不如顯式指定精確,
-
對于可能生成檔案的工具來說,裝配資訊可能不可用
-
容器內的多個 bean 定義可能與要自動裝配的 setter 方法或建構式引數指定的型別匹配,如果是裝配陣列、集合、map這沒有問題,但是,對于期望單個值的依賴項,這種歧義不會被任意解決,如果沒有唯一的 bean 定義可用,則會引發例外,
autowire如何使用
當使用基于 XML 的配置元資料時,可以使用 <bean/> 元素的 autowire 屬性為 bean 定義指定自動裝配模式,共4種模式可以指定,
| 模式 | 說明 |
|---|---|
| no | (默認)不自動裝配, Bean 參考必須由 ref 元素定義, |
| byName | 按屬性名稱自動裝配, Spring 尋找與需要自動裝配的屬性同名的 bean, |
| byType | 根據型別自動裝配,如果容器中恰好存在一個屬性型別的 bean,則讓屬性自動裝配;如果存在多個,則會拋出一個致命例外,表明不能為該 bean 使用 byType 自動裝配;沒有匹配的 bean,什么也沒有發生(屬性未設定) |
| constructor | 類似于 byType 但適用于建構式引數,如果容器中沒有一個建構式引數型別的 bean,則會引發致命錯誤, |
使用
byType或constructor自動裝配模式,可以裝配陣列和或是指定型別的集合,
來,直接上案例,
定義幾個簡單類
ServiceA依賴RepositoryA和RepositoryB
public class ServiceA {
private RepositoryA repositoryA;
private RepositoryB repositoryB;
// 忽略 Getter Setter
}
public class RepositoryA implements RepositoryBase {
}
public class RepositoryB implements RepositoryBase{
}
組態檔中指定自動裝配
<bean id="serviceA" autowire="byType"/> <bean /> <bean />
運行測驗驗證
@org.junit.Test public void test() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo05/spring1.xml"); ServiceA serviceA = context.getBean(ServiceA.class); RepositoryA repositoryA = context.getBean(RepositoryA.class); RepositoryB repositoryB = context.getBean(RepositoryB.class); System.out.println(serviceA); System.out.println(serviceA.getRepositoryA() == repositoryA); System.out.println(serviceA.getRepositoryB() == repositoryB); context.close(); }
測驗結果: ServiceA依賴RepositoryA和RepositoryB,容器自動裝配成功
ServiceA{repositoryA=com.crab.spring.ioc.demo05.RepositoryA@150c158, repositoryB=com.crab.spring.ioc.demo05.RepositoryB@4524411f}
true
true
測驗autowire="constructor"
定義測驗類
public class ServiceB {
private RepositoryA repositoryA;
private RepositoryB repositoryB;
public ServiceB(RepositoryA repositoryA, RepositoryB repositoryB) {
this.repositoryA = repositoryA;
this.repositoryB = repositoryB;
}
@Override
public String toString() {
return "ServiceB{" +
"repositoryA=" + repositoryA +
", repositoryB=" + repositoryB +
'}';
}
}
組態檔
<bean id="serviceA" autowire="constructor"/>
<bean />
<bean />
測驗方法及結果
@org.junit.Test public void test_by_name() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo05/spring2.xml"); ServiceB serviceB = context.getBean(ServiceB.class); System.out.println(serviceB); context.close(); } // 輸出 符合預期 ServiceB{repositoryA=com.crab.spring.ioc.demo05.RepositoryA@3ecd23d9, repositoryB=com.crab.spring.ioc.demo05.RepositoryB@569cfc36}
autowire-candidate 和primary配合自動裝配
指定bean不參與自動裝配
在每個 bean 的基礎上,可以從自動裝配中排除 bean,在 Spring 的 XML 格式中,將 <bean/> 元素的 autowire-candidate 屬性設定為 false,注意:僅在按型別自動裝配時生效,
<bean id="serviceA" autowire="constructor"/> <bean /> <bean /> <!--不參與自動裝配--> <bean id="repositoryB2" autowire-candidate="false"/>
指定bean作為自動裝配的主要候選人
<bean/> 標簽上的元素primary可以指定bean作為自動裝配時主要候選人
注意:僅在按型別自動裝配生效,
<!--主要候選人-->
<bean id="repositoryB3" primary="true"/>
全域配置默認自動裝配模式 default-autowire
<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"
default-autowire="byType"
>
全域限制自動裝配候選者
頂級 <beans/> 元素在其 default-autowire-candidates 屬性中接受一個或多個模式,例如,要將自動裝配候選狀態限制為名稱以 Repository 結尾的任何 bean,請提供值 *Repository,
<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"
default-autowire="byName"
default-autowire-candidates="Repository*"
>
總結
本文介紹和使用autowire來實作自動裝配,分為全域和區域配置,區域優先,下一篇寫bean的作用域,
本篇原始碼地址: https://github.com/kongxubihai/pdf-spring-series/tree/main/spring-series-ioc/src/main/java/com/crab/spring/ioc/demo05
知識分享,轉載請注明出處,學無先后,達者為先!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/422982.html
標籤:Java
上一篇:JavaFx 軟體重啟功能實作
