提到spring,第一印象就是DI與IOC,雖然有概念上的解釋,但是要理解這些概念還是需要?jiǎng)邮诌M(jìn)行試驗(yàn)
。如果要深入了解spring的原來,那么最先了解得就應(yīng)該是spring容器。Spring提供了兩種類型的IOC容
器實(shí)現(xiàn):
1.beanFactory: IOC 容器的基本實(shí)現(xiàn)。
2.ApplicationContext: 提供了更多的高級(jí)特性,是beanFactory的子接口。
在spring的應(yīng)用中,經(jīng)常見到的代碼就是如下典型的從容器中獲取bean實(shí)例的代碼:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
OrderService service = (OrderService)ctx.getbean("personService");
第一行代碼就是創(chuàng)建一個(gè)IOC容器的實(shí)例。BeanFactory、ApplicationContext只是接口,在應(yīng)用中
需要實(shí)例化其實(shí)現(xiàn)類。ApplicationContext實(shí)現(xiàn)類有以下三種是經(jīng)常要用到的:
ClassPathXmlApplicationContext: 從 classpath 下加載配置文件
FileSystemXmlApplicationContext: 從文件系統(tǒng)中加載配置文件
XmlWebApplicationContext: 只能用于 web 應(yīng)用
無論使用何種方式, 配置文件時(shí)相同的。但是由于ApplicationContext提供了更多的附加功能,比
如它提供了文本信息解析工具、載入資源的通用方法等等,所以使用的時(shí)候大部分都是用該接口。在web
應(yīng)用中通常都是通過ClassPathXmlApplicationContext去類路徑下加載配置文件,生成一個(gè)IOC容器并管
理配置文件中配置的bean。
Spring提供了強(qiáng)大的IOC容器來管理組成應(yīng)用程序中的bean(組件)。要利用容器提供的服務(wù),就必須
配置bean,讓這些bean運(yùn)行在Spring IOC容器中。為了讓Spring IOC 容器能夠?qū)ean進(jìn)行實(shí)例化,每個(gè)
bean 都應(yīng)該提供一個(gè)唯一的名稱和一個(gè)全限定類名。例如下面三種方式實(shí)例化bean:
1.使用類構(gòu)造器實(shí)例化
<bean id="orderService" class="cn.itcast.OrderServiceBean"/>
2.使用靜態(tài)工廠方法實(shí)例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-
method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
3.使用實(shí)例工廠方法實(shí)例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-
method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
第一種方法,IOC容易直接根據(jù)配置文件中的class屬性通過反射創(chuàng)建一個(gè)實(shí)例,使用的是該類的默
認(rèn)構(gòu)造方法。第二種則是調(diào)用class指定的工廠類的工廠方法,來返回一個(gè)相應(yīng)的bean實(shí)例,值得注意的
是工廠類的方法是靜態(tài)方法,所以不用產(chǎn)生工廠本身的實(shí)例。而第三種則不同,它除了配置與第二種相
同外,唯一的不同就是方法不是靜態(tài)的,所以創(chuàng)建bean的實(shí)例對(duì)象時(shí)需要先生成工廠類的實(shí)例。
實(shí)例了bean對(duì)象時(shí),需要對(duì)其中的屬性也進(jìn)行賦值,這時(shí)就是經(jīng)常被提及的依賴注入。對(duì)bean的每
個(gè)簡(jiǎn)單類型的屬性來說,可以為其制定<value>元素。Spring會(huì)嘗試將值轉(zhuǎn)換為該屬性的聲明類型。比較
常用的有:
1.setter注入使用<property>元素,使用name屬性指定bean的屬性名稱。優(yōu)點(diǎn): setter 方法可以
自動(dòng)生成,簡(jiǎn)單。缺點(diǎn): 組件使用者或許會(huì)忘記給組件注入它需要的依賴; 在第一次注入后,依賴可能
會(huì)因?yàn)?setter 方法的調(diào)用而被修改。
2.構(gòu)造器注入在 <constructor-arg>元素里聲明屬性,因?yàn)闃?gòu)造器的參數(shù)是基于位置的, 所以
<constructor-arg>中沒有name屬性。優(yōu)點(diǎn): 解決了setter注入的缺點(diǎn)。缺點(diǎn): 需通過參數(shù)位置來確定參
數(shù); 若組件有多個(gè)依賴需要注入, 會(huì)導(dǎo)致構(gòu)造器參數(shù)列表非常冗長(zhǎng)。
IOC容器里可能會(huì)聲明很多的bean,這些bean之間的依賴關(guān)系通常會(huì)比較復(fù)雜。使用setter注入并不
能保證屬性一定會(huì)被注入。spring通過依賴檢查來檢查屬性:
1.Spring 的依賴檢查特性可以檢查bean上的某些類型的所有屬性是否被設(shè)置。
2.Spring 的依賴檢查特性只需在<bean>的dependency-check 屬性里指定依賴檢查模式即可。
3.Spring 的依賴檢查特性只能檢查屬性是否被設(shè)置,但對(duì)設(shè)置的屬性值是 null 的情況則無能為力
。
4.Spring 的依賴檢查特性只對(duì)屬性是否通過 setter 方法設(shè)置進(jìn)行檢查。 所以, 即使通過構(gòu)造器
注入,依然會(huì)拋出異常。
以上是通過配置文件來檢查,另外一種方式就是通過@Required注解檢查屬性。Spring的依賴檢查特
性只能檢查某些類型的所有屬性。不能只針對(duì)個(gè)別屬性進(jìn)行檢查。
RequiredAnnotationbeanPostProcessor 是Spring的bean后置處理器,它檢查所有具有@Required注解的
屬性是否已被設(shè)置。bean后置處理器是一種特殊類型的Spring bean,它能夠在每個(gè)bean實(shí)例化后執(zhí)行一
些額外的工作。要激活bean后置處理器來進(jìn)行屬性檢查,必須在Spring IOC容器里注冊(cè)它。
RequiredAnnotationbeanPostProcessor只能檢查屬性是否被設(shè)置,但對(duì)設(shè)置的屬性值是 null 的情況則
無能為力。
聯(lián)系客服