Java程序员从笨鸟到菜鸟之(七十)细谈Spring(三)IOC和spring基本配置详解
對于IoC?的一些知識點,相信大家都知道他在spring框架中所占有的地位,應該可以算的上是核心之一吧,所以IOC是否理解清楚,決定了大家對Spring整個框架的理解?
Ioc的理解
spring?的兩個核心概念:一個是控制反轉IoC,也可以叫做依賴注入DI。還有一個是面向切面編程AOP。
控制反轉:當某個Java?對象需要(依賴)另一個java?對象時,不
是自身直接創建依賴對象,而是由實現IoC?的容器(如spring?框架的IoC容器)來創建,并將它注入需要這個依賴對象的java?對象中。
spring?的容器
spring?管理的基本單元是Bean,在spring?的應用中,所有的組件都是一個個的Bean,它可以是任何的java?對象。spring?負責創建這些Bean的實例。并管理生命周期。而spring?框架是通過其內置的容器來完成Bean?的管理的,Bean?在spring?的容器中生存著,使用時只需要通過它提供的一些方法從其中獲取即可。
spring?的容器有兩個接口:BeanFactory?和ApplicationContext?這兩個接口的實例被陳為spring?的上下文。
[java]?view plaincopy print?
注:由于ApplicationContext是基于BeanFactory之上的,所以,一般ApplicationContext功能比較強大,建議使用
ApplicationContext經常用到的三個實現:
1.ClassPathXmlApplicationContext:從類路徑中的XML文件載入上下文定義信息。把上下文定義文件當成類路徑資源。
2.FileSystemXmlApplicationContext:從文件系統中的XML文件載入上下文定義信息。
3.XmlWebApplicationContext:從Web系統中的XML文件載入上下文定義信息。
?
一:spring?的依賴注入
1)、構造器注入
[html]?view plaincopy print?
注:這種注入方式很少用,如果是注入對象一般為上例注入,但有時要注入基本數據類型,一般用下面方法注入
[html]?view plaincopy print?
如果構造方法不只一個參數時,應指明所注入參數的索引或者數據類型,例如:
[html]?view plaincopy print?
2)、設值(set?方法)注入
[html]?view plaincopy print?
注:<property?name="accountDaoImpl"?ref="accoutDaoImpl"/>
相當于調用set?AccountDaoImpl方法,把值設為accoutDaoImpl
3)接口注入(很少用)
二:?xml?裝配Bean屬性含義
1.id:指定該Bean?的唯一標識。
2.class:指定該Bean?的全限定名。
3.name:為該Bean?指定一到多個別名。多個別名可以用“,”和“;”分割。
4.autowire:指定該Bean?的屬性的裝配方式。
所謂自動裝配是指在<BEAN>標簽中不用指定其依賴的BEAN,而是通過配置的自動裝配來自動注入依賴的BEAN,這種做法讓我們的配置更加簡單
1)no:不使用自動裝配。必須通過ref?元素指定依賴,這是默認設置。由于顯式指定協作者可以使配置更靈活、更清晰,因此對于較大的部署配置,推薦采用該設置。而且在某種程度上,它也是系統架構的一種文檔形式。
[html]?view plaincopy print?
備注:有property?屬性指定ref
2)byName:根據屬性名自動裝配。此選項將檢查容器并根據
名字查找與屬性完全一致的bean,并將其與屬性自動裝配。例如,在
bean?定義中將autowire?設置為by?name,而該bean?包含master?屬性(同時提供setMaster(..)方法),Spring?就會查找名為master?的bean?定義,并用它來裝配給master?屬性。
<bean?id="bean1"?class="cn.csdn.service.Bean1"
scope="singleton"?autowire="byName"/>
備注:沒有property?屬性
3)byType:如果容器中存在一個與指定屬性類型相同的
bean,那么將與該屬性自動裝配。如果存在多個該類型的bean,那么
將會拋出異常,并指出不能使用byType?方式進行自動裝配。若沒有找到相匹配的bean,則什么事都不發生,屬性也不會被設置。如果你不希望這樣,那么可以通過設置dependency-check="objects"讓Spring?拋出異常。
備注:spring3.0?以上不拋異常。
<bean?id="bean1"?class="cn.csdn.service.Bean1"
scope="singleton"?autowire="byType"/>
備注:沒有property?屬性
4)Constructor:與byType?的方式類似,不同之處在于它應用
于構造器參數。如果在容器中沒有找到與構造器參數類型一致的bean,那么將會拋出異常。
<bean?id="bean1"?class="cn.csdn.service.Bean1"
scope="singleton"autowire="constructor"/>
備注:沒有property?屬性
5)autodetect:通過bean?類的自省機制(introspection)來決定是使用constructor?還是byType?方式進行自動裝配。如果發現默認的
構造器,那么將使用byType?方式。
<bean?id="bean1"?class="cn.csdn.service.Bean1"
scope="singleton"?autowire="autodetect"/>
5.scope:指定該Bean?的生存范圍
scope用來聲明IOC容器中的對象應該處的限定場景或者說該對象的存活空間,即在IOC容器在對象進入相應的scope之前,生成并裝配這些對象,在該對象不再處于這些scope的限定之后,容器通常會銷毀這些對象。
1)?singleton類型的bean定義,在一個容器中只存在一個實例,所有對該類型bean的依賴都引用這一單一實例
2)?scope為prototype的bean,容器在接受到該類型的對象的請求的時候,會每次都重新生成一?個新的對象給請求方,雖然這種類型的對象的實例化以及屬性設置等工作都是由容器負責的,但是只要準備完畢,并且對象實例返回給請求方之后,容器就不在擁有?當前對象的引用,請求方需要自己負責當前對象后繼生命周期的管理工作,包括該對象的銷毀
3)?request?,session和global?session
這三個類型是spring2.0之后新增的,他們只適用于web程序,通常是和XmlWebApplicationContext共同使用
request:
<bean?id?="requestPrecessor"?class="...RequestPrecessor"???scope="request"?/>
Spring容器,即XmlWebApplicationContext?會為每個HTTP請求創建一個全新的RequestPrecessor對象,當請求結束后,,該對象的生命周期即告結束
session
<bean?id?="userPreferences"?class="...UserPreferences"???scope="session"?/>
Spring容器會為每個獨立的session創建屬于自己的全新的UserPreferences實例,他比request?scope的bean會存活更長的時間,其他的方面真是沒什么區別。
global?session:
<bean?id?="userPreferences"?class="...UserPreferences"???scope="globalsession"?/>?
global?session只有應用在基于porlet的web應用程序中才有意義,他映射到porlet的global范圍的session,如果普通的servlet的web?應用中使用了這個scope,容器會把它作為普通的session的scope對待。
6.init-method:指定該Bean?的初始化方法。destroy-method:指定該Bean?的銷毀方法。這個就像servlet中init和destroy方法一樣,只不過這里在配置文件配置的
7.abstract:指定該Bean?是否為抽象的。如果是抽象的,則
spring?不為它創建實例。
8.parent?
如果兩個Bean?的屬性裝配信息很相似,那么可以利用繼
承來減少重復的配置工作。
<!--?裝配Bean?的繼承
父類作為模板,不需要實例化,設置abstract=”true”-->
`?<bean?id=”parent”?class=”cn.csdn.service.Parent”
abstract=”true”>
<property?name=”name”?value=”z_xiaofei168”/>
<property?name=”pass”?value=”z_xiaofei168”/>
</bean>
<!--?裝配Bean?的繼承
子類中用parent?屬性指定父類標識或別名
子類可以覆蓋父類的屬性裝配,也可以新增自己的屬性裝配
-->
`?<bean?id=”child”?class=”cn.csdn.service.Chlid”
parent=”parent”>
<property?name=”pass”?value=”123123”/>
<property?name=”age”?value=”22”/>
</bean>
三:裝配Bean?的各種類型屬性值
1..簡單類型屬性值的裝配
[html]?view plaincopy print?
2.引用其他Bean?的裝配
[html]?view plaincopy print?
另外一種不常使用的配置方式是在property?元素中嵌入
一個bean?元素來指定所引用的Bean.
[html]?view plaincopy print?
3.集合的裝配
其實集合的裝配并不是復雜,反而感覺到很簡單,用一個例子來說明問題吧:
配置如下:
[html]?view plaincopy print?
四:Spring?bean生命周期
? ??? 在傳統的Java應用中,Bean的生命周期非常簡單。?Java的關鍵詞new用來實例化Bean(或許他是非序列化的)。這樣就夠用了。?相反,Bean的生命周期在Spring容器中更加細致。?理解Spring?Bean的生命周期非常重要,因為你或許要利用Spring提供的機會來訂制Bean的創建過程。?
?bean生命周期
1.容器尋找Bean的定義信息并且將其實例化。?
2.受用依賴注入,Spring按照Bean定義信息配置Bean的所有屬性。?
3.如果Bean實現了BeanNameAware接口,工廠調用Bean的setBeanName()方法傳遞Bean的ID。?
4.如果Bean實現了BeanFactoryAware接口,工廠調用setBeanFactory()方法傳入工廠自身。?
5.如果BeanPostProcessor和Bean關聯,那么它們的postProcessBeforeInitialzation()方法將被調用。?
6.如果Bean指定了init-method方法,它將被調用。?
7.最后,如果有BeanPsotProcessor和Bean關聯,那么它們的postProcessAfterInitialization()方法將被調用。?
到這個時候,Bean已經可以被應用系統使用了,并且將被保留在Bean?Factory中知道它不再需要。?
有兩種方法可以把它從Bean?Factory中刪除掉。?
1.如果Bean實現了DisposableBean接口,destory()方法被調用。?
2.如果指定了訂制的銷毀方法,就調用這個方法。?
Bean在Spring應用上下文的生命周期與在Bean工廠中的生命周期只有一點不同,?唯一不同的是,如果Bean實現了ApplicationContextAwre接口,setApplicationContext()方法被調用。?
只有singleton行為的bean接受容器管理生命周期。?
non-singleton行為的bean,Spring容器僅僅是new的替代,容器只負責創建。?
對于singleton?bean,Spring容器知道bean何時實例化結束,何時銷毀,?Spring可以管理實例化結束之后,和銷毀之前的行為,管理bean的生命周期行為主要未如下兩個時機:?
Bean全部依賴注入之后?
Bean即將銷毀之前?
1)依賴關系注入后的行為實現:?
有兩種方法:A.編寫init方法??B.實現InitializingBean接口?
afterPropertiesSet和init同時出現,前者先于后者執行,使用init方法,需要對配置文件加入init-method屬性?
2)bean銷毀之前的行為?
有兩種方法:A.編寫close方法??B.實現DisposableBean接口?
destroy和close同時出現,前者先于后者執行,使用close方法,需要對配置文件加入destroy-method屬性?
?總體上分只為四個階段??
?1.?BeanFactoyPostProcessor實例化??
?2.?Bean實例化,然后通過某些BeanFactoyPostProcessor來進行依賴注入??
?3.?BeanPostProcessor的調用.Spring內置的BeanPostProcessor負責調用Bean實現的接口:?BeanNameAware,?BeanFactoryAware,?ApplicationContextAware等等,等這些內置的BeanPostProcessor調用完后才會調用自己配置的BeanPostProcessor??
?4.Bean銷毀階段??
注:xml依賴注入中的bean.xml例子:
[html]?view plaincopy print?
總結
以上是生活随笔為你收集整理的Java程序员从笨鸟到菜鸟之(七十)细谈Spring(三)IOC和spring基本配置详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java程序员从笨鸟到菜鸟之(十三)ja
- 下一篇: Java程序员从笨鸟到菜鸟之(七十三)细