Tapestry IoC容器從歷史上來說,是從從HiveMind繼承發(fā)展而來,但是HiveMind和目前大紅大紫的Spring都不能滿足Tapestry的一些特定的需求,所以全新開發(fā)了一套IoC的容器。
其核心思想就是使用Java代碼自身來解決依賴注入而不是由Xml之類的配置文件來完成,這和Guice的思想是非常相似的,Lewis也承認(rèn)從Guice那里借鑒了不少。
另外需要說明一下的是,Tapesty還從中國的一個(gè)非常古老但又充滿哲理的游戲--圍棋中借鑒了一些術(shù)語和思想。大意是圍棋中經(jīng)常要把棋子走的輕盈(Lightness),讓每個(gè)棋子都能盡量地高效。編程也一樣要輕量(Lightness)。
IoC容器中使用的一些概念,充分理解這些概念會(huì)對Tapesty IoC容器有一個(gè)總體上的感性認(rèn)識。
Tapestry IoC中的最基本的組成單元是服務(wù)(Service)。服務(wù)一般由一個(gè)接口和一個(gè)接口的實(shí)現(xiàn)組成。每個(gè)服務(wù)都有一個(gè)全局唯一的標(biāo)識(ID)。
數(shù)個(gè)或者多個(gè)服務(wù)組成一個(gè)模塊。模塊中會(huì)包括一個(gè)模塊定義類,在這個(gè)類里面有一系列的靜態(tài)或者成員方法
,用于定義服務(wù)、裝飾服務(wù)、或者添加配置項(xiàng)。
這個(gè)類中的方法定義服務(wù),并同時(shí)負(fù)責(zé)實(shí)例化服務(wù)的實(shí)現(xiàn)類。
這些方法被稱為:服務(wù)創(chuàng)建 (build) 方法。
注冊表(Registry) 是外部世界與服務(wù)和模塊交互的媒介。通過注冊表,使用服務(wù)的ID或者服務(wù)接口,才有可能獲得一個(gè)服務(wù)(服務(wù)ID是大小寫不敏感的,這是Tapestry的一個(gè)隨處可見的特性)。
服務(wù)可以由服務(wù)裝飾方法進(jìn)行裝飾(decorate)。這些裝飾方法會(huì)創(chuàng)建攔截器(interceptor)來包裝核心的服務(wù)實(shí)現(xiàn),
在外面添加諸如日志、權(quán)限檢查、數(shù)據(jù)庫事務(wù)之類的行為。攔截器需要實(shí)現(xiàn)同樣服務(wù)接口,這實(shí)際上就是一個(gè)裝飾模式的應(yīng)用。
下面是關(guān)于服務(wù)的一個(gè)很重要的概念:配置(Configuration)。
在Tapestry的AppModule.java中最常見的是兩類方法,一類是前面剛剛介紹過的服務(wù)創(chuàng)建方法,一般是以build開頭的。另一大類就是添加配置的方法了,一般是以contribute開頭。
服務(wù)可以根據(jù)配置項(xiàng)靈活配置,配置的數(shù)據(jù)結(jié)構(gòu)可以是Map、集合或者是有序列表。
服務(wù)自己定義允許什么類型的配置項(xiàng)可以被添加到配置中,Tapestry中把添加配置項(xiàng)的動(dòng)作稱之為貢獻(xiàn)(Contribute)。
配置可以由一個(gè)或者多個(gè)模塊分別貢獻(xiàn)而成。通過調(diào)用服務(wù)貢獻(xiàn)方法(Service Contributor Methods)來把配置對象添加到配置中。
服務(wù)的狀態(tài)演變:
服務(wù)只有在需要的時(shí)候才會(huì)被實(shí)例化。在這里,“需要”的意思是服務(wù)的某個(gè)方法被調(diào)用了。開始的時(shí)候,從外界來看,服務(wù)只是一個(gè)實(shí)現(xiàn)了服務(wù)接口的代理。
當(dāng)這個(gè)代理的方法第一次被實(shí)際調(diào)用的時(shí)候,完整的服務(wù)(也就是服務(wù)的實(shí)現(xiàn)類)才會(huì)真正地被構(gòu)造。
并且這個(gè)構(gòu)造過程是線程安全的。
實(shí)例化服務(wù)、進(jìn)行依賴注入、裝飾服務(wù)這就是服務(wù)實(shí)現(xiàn)(Realization)的所有組成部分。通過這三步一個(gè)服務(wù)才從虛擬狀態(tài)(只是一個(gè)代理)轉(zhuǎn)換成真實(shí)狀態(tài)(完全的實(shí)例化,等待被使用了)。
服務(wù)的范圍:服務(wù)的缺省范圍是單例的,另外也可以與當(dāng)前線程綁定.
依賴項(xiàng)是服務(wù)實(shí)現(xiàn)類所需要的其他服務(wù)。依賴項(xiàng)可以由服務(wù)創(chuàng)建方法通過構(gòu)造函數(shù)、方法參數(shù)注入進(jìn)來。
注入點(diǎn)可以是類成員屬性、方法參數(shù)、或者構(gòu)造函數(shù)參數(shù)。通常使用注解來指定注入的類型。