业务层设计之二(ServiceLocator)

来源:百度文库 编辑:神马文学网 时间:2024/04/27 20:46:54
ServiceLocator(服务定位器)
问题
需要以一种统一的,透明的方式定位业务组件和业务服务。
1. 客户端需要定位,访问业务层的组件和服务。
2. 代码难移植。客户端使用JNDI寻址的复杂性,厂商依赖性。
3. 重复创建InitialContext对象,寻址操作,强制类型转换,底层异常和超时处理。
动机
1. 利用JNDI完成业务组件(EJB,JMS),业务服务(数据源)的寻址和调用。
2. 抽取复杂性。寻址机制集中起来,向客户端提供统一的服务访问。
3. 封装各厂商对JNDI注册表的不同实现,并对客户端隐藏这种厂商依赖性和复杂性。
4. 避免初始上下文(initial context)的创建和服务的寻址引起的性能负载。
5. 提供cache功能,减少冗余寻址,改善系统性能。
6. 用利用添加新的业务组件。通过EJB实例句柄对象重建曾经访问过的EJB实例连接。
结构
Client ---->ServiceLocator(cache) ---->InitialContext ----> Target(EJBHome)
客户端: 比如一个业务代表在定位,访问相关的SessionFacade的时候,就充当了服务
定位器的客户端角色。同样,当一个数据访问对象使用ServiceLocator获取一个
JDBC datasource实例的时候,它充当的也是Client的角色。
服务定位器: ServiceLocator封装了API寻址(命名)服务,厂商产品的特定依赖,寻址复
杂性以及业务对象的创建;它对客户端提供一种简单的接口。促进了重用。
缓存: Cache中保留着以前寻址操作的引用,起到了备用的ServiceLocator作用。使用
Cache的唯一目的就是要减少冗余寻址,从而优化ServiceLocator。
初始上下文: InitialContext对象是整个寻址,创建过程的起点。如果一个ServiceLocator
提供不同类型的target组件(EJB,JMS),它就会使用不同类型的上下文对象,其中每
一种上下文对象都 来自不同的服务提供者。
目标: Target也就是Client通过ServiceLocator寻址的业务层/集成层的服务或组件。比如
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;
}
}