业务层设计之二(ServiceLocator)

来源:百度文库 编辑:神马文学网 时间:2024/10/04 05:25:34
业务层设计之二(ServiceLocator) 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;
        }
    }