Pluto體繫結構
我們從闡述Pluto的體繫結構和一些基本概念入手。首先,我們簡要的解釋一下運行Pluto參考實現的Portal,看一看在Portal的體繫結構中,Portal將從哪裡找到portlet容器。其次,我們將詳細的說明Pluto的體繫結構。最後,我們將說明它是如何解決portlet容器的一個挑戰性的問題:portlet的部署。
Portal
Pluto是一個滿足Portlet API規範的Portlet容器的實現,它為開發人員提供了一個運行portlets的工作平台。然而,如果沒有一個磁碟機(driver),也就是 Portal,的支援的話,運行和測試Portlet容器將非常之麻煩。Pluto本身也提供了一個簡單的Portal模組,該模組僅僅是為了滿足 Portlet容器和JSR 168的需要而寫的。如果你需要一個成熟的Portal,請參考Jetspeed項目。Jetspeed項目關注的是Portal本身,而不是Portlet容器。
圖1是Portal的基本體繫結構圖。Portal Web Application處理客戶的請求,從客戶的當前頁中提取出portlets,然後調用portlet容器來獲得每一個portlet的內容。 Portal通過Portlet容器的Invoker API來訪問portlet容器。這些API是portlet容器的主要調用介面,它們為Portal提供了一些基於請求的方法來調用portlet。容器的使用者(即Portal,譯者注)必須實現portlet容器的Container Provider SPI(Service Provider Interface)回調介面,來為portlet容器提供與Portal相關的資訊。最後,portlet容器通過Portlet API調用所有的portlets。
Portlet容器
Portlet容器是portlets的運行時環境,也是每一個Portal的核心組件。Portlet容器需要擷取有關Portal本身的一些資訊,還必須重用Portal的一些基本代碼。因此,Portlet容器可以保證自己與其它的Portal組件之間是完全分開的。也就是說,你可以把一個獨立的Portlet容器插入到任何一個Portal中去,只要它可以滿足Portlet容器的要求,比如實現了所有的SPI。
Portlet容器的Invoker API(也被稱為進入點)是Portlet容器的主要調用介面。這些API包含Portlet容器的生命週期控制方法(init(),destroy ())和基於請求的調用方法(initPage(),performTitle(),portletService()等等)。由於Portlet容器最終是去調用一個portlet,故這些方法的簽名和Portlet API的主要portlet介面很類似,除了一個須額外傳入的portlet ID。Portlet容器可以通過這個額外傳入的portlet ID參數來決定調用哪一個portlet。
除了可以使用Invoker API來調用Portlet容器外,Portal還必須實現Portlet容器定義的SPI。因此,參考實現引入了“Container Service”的概念:Container Service用來定義一些能夠在容器中註冊的可插的組件,這些組件要麼提供一些基本的功能,要麼對容器進行擴充。Pluto參考實現定義了下面這些內建的Container Service(前四個是運行Portlet容器所必須實現的,而第五個則是可選的):
- Information Provider(資訊提供者):為Portlet容器提供關於Portal及其架構的資訊。通過該介面只能夠獲得一些已知的或存在Portal中的資訊。這些資訊包括帶導航狀態(navigational state)的URL產生、portlet上下文(portlet context)、portlet模式(portlet mode)和視窗狀態(window state)控制。
- Factory Manager(工廠管理者):定義了如何通過工廠獲得一個實現(一般的Portal應該已經實現了這樣的介面)。
- Log Service(Log Service):定義了輸出日誌的方法(一般的Portal應該已經實現了這樣的介面)。
- Config Service(佈建服務):定義了如何獲得配置值(一般的Portal應該已經實現了這樣的介面)。
- Property Manager(屬性管理者,可選):該服務讓Portal可以獲得JSR 168規範中定義的屬性的值。
嚴格的說,Portlet Object Model(Portlet物件模型)也是一個SPI,但與其它的SPI相比,它處在一個特殊的位置上。因此我們不把它看成是Container Service的一部分,因為它處理所有的portlet對象,並包含了一些混雜的介面。
圖2:Portlet容器的體繫結構
Portlet的部署
Portlet容器是構建在Servlet容器之上的,所以它可以重用Servlet容器的許多功能。為了達到這一點,portlet容器必須把一些 servlet的屬性注入到每一個portlet應用的war檔案中,3所示。Portlet組件的部署器將在原先的war檔案中注入一個新的或者修改過的web.xml,再為每個portlet注入一個servlet包裹器,以此作為調用點。然後,portlet部署器將把這個修改過的war檔案傳給應用伺服器的部署器,以此來把它部署到應用伺服器的系統中。當一個portlet被調用時,portlet容器將調用注入的servlet包裹器,把這作為被部署的portlet的war檔案的進入點。
圖3:參考實現中portlet的部署
Pluto和WSRP標準
JSR 168規範和Web Service for Remote Portlets(WSRP)標準有高度的一致性。這兩個同時出現的標準都發布了開放源碼的實現,它們的實現都完成了在相應的規範中定義的所有必要功能。這兩個標準都把能很好的互相協作作為它們共同的目標。因此,WSRP portlets在portlet容器中既可以作為消費者運行,也可以作為生產者運行。
Pluto項目必須支援在一個Portal中運行多個portlet容器。因此,Pluto Portlet容器可以被多次初始化。更重要的是,它可以以不同的方式運行,每個portlet容器都使用一個不同的SPI實現。