ServiceLocator(服務(wù)定位器)
問(wèn)題
需要以一種統一的,透明的方式定位業(yè)務(wù)組件和業(yè)務(wù)服務(wù)。
1. 客戶(hù)端需要定位,訪(fǎng)問(wèn)業(yè)務(wù)層的組件和服務(wù)。
2. 代碼難移植??蛻?hù)端使用JNDI尋址的復雜性,廠(chǎng)商依賴(lài)性。
3. 重復創(chuàng )建InitialContext對象,尋址操作,強制類(lèi)型轉換,底層異常和超時(shí)處理。
動(dòng)機
1. 利用JNDI完成業(yè)務(wù)組件(EJB,JMS),業(yè)務(wù)服務(wù)(數據源)的尋址和調用。
2. 抽取復雜性。尋址機制集中起來(lái),向客戶(hù)端提供統一的服務(wù)訪(fǎng)問(wèn)。
3. 封裝各廠(chǎng)商對JNDI注冊表的不同實(shí)現,并對客戶(hù)端隱藏這種廠(chǎng)商依賴(lài)性和復雜性。
4. 避免初始上下文(initial context)的創(chuàng )建和服務(wù)的尋址引起的性能負載。
5. 提供cache功能,減少冗余尋址,改善系統性能。
6. 用利用添加新的業(yè)務(wù)組件。通過(guò)EJB實(shí)例句柄對象重建曾經(jīng)訪(fǎng)問(wèn)過(guò)的EJB實(shí)例連接。
結構
Client ---->ServiceLocator(cache) ---->InitialContext ----> Target(EJBHome)
客戶(hù)端: 比如一個(gè)業(yè)務(wù)代表在定位,訪(fǎng)問(wèn)相關(guān)的SessionFacade的時(shí)候,就充當了服務(wù)
定位器的客戶(hù)端角色。同樣,當一個(gè)數據訪(fǎng)問(wèn)對象使用ServiceLocator獲取一個(gè)
JDBC datasource實(shí)例的時(shí)候,它充當的也是Client的角色。
服務(wù)定位器: ServiceLocator封裝了API尋址(命名)服務(wù),廠(chǎng)商產(chǎn)品的特定依賴(lài),尋址復
雜性以及業(yè)務(wù)對象的創(chuàng )建;它對客戶(hù)端提供一種簡(jiǎn)單的接口。促進(jìn)了重用。
緩存: Cache中保留著(zhù)以前尋址操作的引用,起到了備用的ServiceLocator作用。使用
Cache的唯一目的就是要減少冗余尋址,從而優(yōu)化ServiceLocator。
初始上下文: InitialContext對象是整個(gè)尋址,創(chuàng )建過(guò)程的起點(diǎn)。如果一個(gè)ServiceLocator
提供不同類(lèi)型的target組件(EJB,JMS),它就會(huì )使用不同類(lèi)型的上下文對象,其中每
一種上下文對象都 來(lái)自不同的服務(wù)提供者。
目標: Target也就是Client通過(guò)ServiceLocator尋址的業(yè)務(wù)層/集成層的服務(wù)或組件。比如
EJBHome,DataSource,JMS ConnectionFactory,QueueConnectionFactory。
示例
public class ServiceLocatorImpl implements ServiceLocator, java.io.Serializable {
protected HttpSession session;
protected WebClientController wcc;
public ServiceLocatorImpl() { }
public WebClientController getWebClientController() {
WebClientController wcc =(WebClientController)session.getAttribute
(WebKeys.WEB_CLIENT_CONTROLLER);
if ( wcc == null ) {
try {
InitialContext ic = new InitialContext();
String wccClassName = (String)
ic.lookup(JNDINames.WEB_CLIENT_CONTROLLER_IMPL);
wcc = (WebClientController)
Beans.instantiate(this.getClass().getClassLoader(), wccClassName);
wcc.init(session);
} catch (Exception exc) {
exc.printStackTrace();
throw new RuntimeException ("Cannot create bean of class
WebClientController");
}
session.setAttribute(WebKeys.WEB_CLIENT_CONTROLLER, wcc);
}
return wcc;
}
public void sessionCreated(HttpSessionEvent se) {
this.session = se.getSession();
wcc = getWebClientController();
this.session.setAttribute(WebKeys.SERVICE_LOCATOR, this);
}
public void sessionDestroyed(HttpSessionEvent se) {
if (wcc != null) wcc.destroy();
wcc = null;
}
}
聯(lián)系客服