8.自動裝配
Spring能自動裝配Bean與Bean之間的依賴關(guān)系,即使無需使用ref顯式指定依賴Bean审丘。
Spring的自動裝配使用autowire屬性指定,每一個<bean/>元素都可以指定autowire屬性泥从,也就是說在Spring容器中完全可以讓某些Bean自動裝配谚赎,而某些Bean不沒使用自動裝配。
自動裝配可以減少配置文件的工作量岛杀,但是降低了依賴關(guān)系的透明性和依賴性阔拳。
spring中有四種自動裝配類型,分別為:byName类嗤,byType糊肠,constructor,autodetect遗锣,下面來分別介紹一下這些是如何自動裝配的
<bean id="foo" class="...Foo" autowire="autowire type">
1.byName:尋找和屬性名相同的bean,若找不到货裹,則裝不上。
2.byType:尋找和屬性類型相同的bean,找不到,裝不上,找到多個拋異常精偿。
3.constructor:查找和bean的構(gòu)造參數(shù)一致的一個或多個bean弧圆,若找不到或找到多個,拋異常还最。按照參數(shù)的類型裝配
4.autodetect: (3)和(2)之間選一個方式墓阀。不確定性的處理與(3)和(2)一致。
例如:
<bean id="bar" class="Bar" autowire="byName"/>
在介紹實例之前先要創(chuàng)建結(jié)構(gòu)拓轻,我們以一個實例開始斯撮,用Customers來做實例,實例的結(jié)構(gòu)為:
我們要創(chuàng)建一個CustomersServiceImpl.Java扶叉,內(nèi)容為:
publicclass CustomersServiceImpl implements CustomersService {
private CustomersDao customersDao = new CustomersDaoImpl();
private BaseDao baseDao;
// set方法注入
publicvoid setCustomersDao(CustomersDao customersDao) {
this.customersDao = customersDao;
}
publicvoid setBaseDao(BaseDao baseDao) {
this.baseDao = baseDao;
}
public CustomersDao getCustomersDao() {
returncustomersDao;
}
public BaseDao getBaseDao() {
returnbaseDao;
}
}
在xml中對上面的兩個屬性進行注入 1.首先來介紹一下沒有autowire的效果
<bean id="customersServiceImpl" class="cn.csdn.hr.service.CustomersServiceImpl">
<property name="customersDao">
<bean class="cn.csdn.hr.dao.CustomersDaoImpl"/>
</property>
<property name="baseDao">
<bean class="cn.csdn.hr.dao.BaseHibernateDaoImpl"/>
</property>
</bean>
也可以用ref引用的方式來寫勿锅,可以寫為:
<bean id="customersServiceImpl" class="cn.csdn.hr.service.CustomersServiceImpl">
<property name="customersDao">
<ref bean="customersDao"/>
</property>
<property name="baseDao">
<ref bean="baseDao"/>
</property>
</bean>
<bean id="customersDao" class="cn.csdn.hr.dao.CustomersDaoImpl"/>
<bean id="baseDao" class="cn.csdn.hr.dao.BaseHibernateDaoImpl"/>
這樣,在junit中測試為:
publicvoid test() {
//獲取應(yīng)用程序上下文對象
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:beanAuto.xml");
CustomersServiceImpl customersServiceImpl = (CustomersServiceImpl) ac.getBean("customersServiceImpl");
System.out.println("baseDao的實例"+customersServiceImpl.getBaseDao());
System.out.println("customersDao的實例"+customersServiceImpl.getCustomersDao());
}
我們可以得到:
baseDao的實例cn.csdn.hr.dao.BaseHibernateDaoImpl@12be1bd
customersDao的實例cn.csdn.hr.dao.CustomersDaoImpl@1f17e77
2.當(dāng)把autowire設(shè)置為byName的時候枣氧,可以省略很多的代碼溢十,在junit和其他都不動的情況下,只改變xml达吞,beanByName.xml中的代碼為:
<bean id="customersServiceImpl" class="cn.csdn.hr.service.CustomersServiceImpl" autowire="byName"/>
<bean id="customersDao" class="cn.csdn.hr.dao.CustomersDaoImpl"></bean>
<bean id="baseDao" class="cn.csdn.hr.dao.BaseHibernateDaoImpl"></bean>
注:當(dāng)autowire="byName"時张弛,cn.csdn.hr.service.CustomersServiceImpl 屬性名與bean的id名稱的名稱相同會自動裝配。
3.當(dāng)把autowire設(shè)置為byType的時候
<bean id="customersServiceImpl" class="cn.csdn.hr.service.CustomersServiceImpl" autowire="byType"/>
<bean id="customersDaoImpl" class="cn.csdn.hr.dao.CustomersDaoImpl"></bean>
<bean id="baseDaoImpl" class="cn.csdn.hr.dao.BaseHibernateDaoImpl"></bean>
注:不可以有相同的類型,也就是說不可以有相同的類名存在吞鸭,id可有可無寺董,但是一般情況下是存在的,它與其他的沒有關(guān)聯(lián)
4.當(dāng)把autowire設(shè)置為*constructor*的時候
<bean id="customersServiceImpl" class="cn.csdn.hr.service.CustomersServiceImpl" autowire="constructor"/>
<bean id="customersDaoImpl" class="cn.csdn.hr.dao.CustomersDaoImpl"/>
<bean id="baseDaoImpl" class="cn.csdn.hr.dao.BaseHibernateDaoImpl"/>
注:在執(zhí)行這個xml的時候刻剥,要有構(gòu)造函數(shù)遮咖,經(jīng)過驗證得出必須有有參構(gòu)造才可以全部得到
5.當(dāng)把autowire設(shè)置為autodetect的時候
<bean id="customersServiceImpl" class="cn.csdn.hr.service.CustomersServiceImpl" autowire="autodetect" />
<bean id="customersDaoImpl" class="cn.csdn.hr.dao.CustomersDaoImpl" />
<bean id="baseDaoImpl" class="cn.csdn.hr.dao.BaseHibernateDaoImpl" />
注意:對于大型的應(yīng)用而言,不鼓勵使用自動裝配
9.依賴檢查
Spring提供一種依賴檢查的功能造虏,可以防止出現(xiàn)配置手誤御吞,或者其他情況的錯誤。
使用依賴檢查可以讓系統(tǒng)判斷配置文件的依賴關(guān)系注入是否完全有效漓藕。
使用依賴檢查陶珠,可以保證Bean的屬性得到了正確的設(shè)置,有時候撵术,某個Bean的特定屬性并不需要設(shè)置值背率,或者某些屬性已有默認值,此時采用依賴檢查就會出現(xiàn)錯誤嫩与,該Bean就不應(yīng)該采用依賴檢查,幸好Spring可以為不同的Bean單獨指定依賴檢查的行為,Spring提供dependency-chech屬性來配置依賴檢查交排,當(dāng)然也可以指定不同的檢查依賴策略划滋。
該屬性有如下值:
none:不進行依賴檢查,沒有指定值的Bean屬性僅僅是沒有設(shè)置值埃篓,這是默認值处坪。
simple:對基本類型和集合(除了合作者Bean)進行依賴檢查。
objects:僅對合作者Bean進行依賴檢查架专。
all:對合作者Bean同窘、基本數(shù)據(jù)類型全部進行依賴檢查。
public class Chinese implements Person{
private Axe axe;
private int age = 30;
//implements method
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age
}
}
<bean id="axe" class="StoneAxe"/>
<bean id="chinese" class="Chinese" dependency-check="all">
<property name="axe" ref="axe"/>
</bean>
以上程序?qū)伋霎惓?雖然Chinese類的age屬性已經(jīng)有了默認值部脚,但配置dependency-check="all"則要求配置文件為所有的屬性都提供正確的值想邦。而age屬性沒有提供值。
二:深入Spring:
1.利用后處理器擴展Spring容器:
Spring容器提供了很好的擴展性委刘,除了可以與各種第三方框架良好的整合外丧没,其IoC容器也允許開發(fā)者進行擴展,這種擴展甚至無需實現(xiàn)BeanFactory或ApplicationContext接口锡移,允許兩個后處理器對IoC容器進行擴展:
Bean后處理器:這種處理器會對容器中的Bean進行后處理呕童,對Bean的功能進行額外的加強。
容器后處理器:這種處理器對IoC容器進行后處理淆珊,用于增強容器的功能夺饲。