用SERVICE LOCATOR 模式实现访问命名服务

<script type="text/javascript"> google_ad_client = "pub-8800625213955058"; /* 336x280, 创建于 07-11-21 */ google_ad_slot = "0989131976"; google_ad_width = 336; google_ad_height = 280; // </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> 在B/S开发中, 我们经常要用到名称服务,如JNDI,XMLNS等。名称服务随不同厂家而不同。每次需要获得名称服务时,需要适当的名称环境信息,然后查找服务,重复查找的成本很高。 此外,在持久性框架中,要求将所有的服务访问都包装到对象中,开发人员不需要知道名称服务后面的平台(数据库)类型,及任何安全信息或地址。在一个大型软件产品间存在多个EJB和多个数据源连接时(我们目前只有一个写死的数据源WEBGL)需要一个类来实现统一的访问管理。 因此,这就要求我们对这些访问进行封装隔离。这时我们就可以利用SERVICE LOCATOR模式。 我们将利用一个文件service.properties来管理所有的命名服务。例子代码实现了EJB本地,数据源的访问。 格式如下: DEFAULTDS=webgl NTCLASSREF=NTHome.class 把它保存在CLASSPATH引用的路径里。 源代码: Package com.learn; import java.util.Hashtable; import java.util.Properties; import java.io.*; import javax.ejb.EJBHome; import javax.naming.InitialContext; import javax.naming.Context; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; public class ServiceLocator { private static ServiceLocator serviceLocatorRef = null; private static Hashtable ejbHomeCache = null; private static Hashtable dataSourceCache = null; private static Properties serviceCache = null; static { serviceLocatorRef = new ServiceLocator(); } private ServiceLocator() { ejbHomeCache = new Hashtable(); dataSourceCache = new Hashtable(); try { String serviceFileName = "service.properties"; serviceCache.load(new FileInputStream(serviceFileName)); } catch (IOException e) { System.out.println(e.toString()); } } /** * 使用singleton.模式静态对象多次调用节省资源 */ public static ServiceLocator getInstance() { return serviceLocatorRef; } /* * 由键获得键值,一般在数据源,XMLNS访问用到这个方法 */ static private String getServiceName(String serviceId) throws ServiceLocatorException{ String serviceName=null; if (serviceCache.containsKey(serviceId)) { serviceName = (String) serviceCache.get(serviceId); } else { throw new ServiceLocatorException( "Unable to locate the service statement requested"); } return serviceName; } /************************************************* * EJB本地类引用 *************************************************/ static private Class getEJBHomeRef(String serviceId) throws ServiceLocatorException { Class homeRef = null; if (serviceCache.containsKey(serviceId)) { homeRef = (Class) serviceCache.get(serviceId); } else { throw new ServiceLocatorException( "Unable to locate the service statement requested"); } return homeRef; } /************************************************************************ * 获得EJBHome对象 ***********************************************************************/ public EJBHome getEJBHome(String serviceId) throws ServiceLocatorException { EJBHome ejbHome = null; try { //先检查缓存是否存在EJBHome接口 if (ejbHomeCache.containsKey(serviceId)) { ejbHome = (EJBHome) ejbHomeCache.get(serviceId); return ejbHome; } else { //如果没有存在,则解析并存到缓存中 Context ctx = new InitialContext(); Object jndiRef = ctx.lookup(serviceId); Object portableObj = PortableRemoteObject.narrow(jndiRef, getEJBHomeRef(serviceId)); ejbHome = (EJBHome) portableObj; ejbHomeCache.put(serviceId, ejbHome); return ejbHome; } } catch (NamingException e) { throw new ServiceLocatorException( "Naming exception error in ServiceLocator.getEJBHome()", e); } } /* * 获得JNDI数据源 */ public Connection getDBConn(String serviceId) throws ServiceLocatorException { Connection conn = null; String serviceName=getServiceName(serviceId); try { /*Checking to see if the requested DataSource is in the Cache*/ if (dataSourceCache.containsKey(serviceId)) { DataSource ds = (DataSource) dataSourceCache.get(serviceId); conn = ( (DataSource) ds).getConnection(); return conn; } else { /* * The DataSource was not in the cache. Retrieve it from JNDI * and put it in the cache. */ Context ctx = new InitialContext(); DataSource newDataSource = (DataSource) ctx.lookup(serviceName); dataSourceCache.put(serviceId, newDataSource); conn = newDataSource.getConnection(); return conn; } } catch (SQLException e) { throw new ServiceLocatorException("A SQL error has occurred in " "ServiceLocator.getDBConn()", e); } catch (NamingException e) { throw new ServiceLocatorException("A JNDI Naming exception has occurred " " in ServiceLocator.getDBConn()", e); } catch (Exception e) { throw new ServiceLocatorException("An exception has occurred " " in ServiceLocator.getDBConn()", e); } } } 异常处理类: package com.learn; public class ServiceLocatorException extends DataAccessException{ public ServiceLocatorException(String pExceptionMsg){ super(pExceptionMsg); } public ServiceLocatorException(String pExceptionMsg, Throwable pException){ super(pExceptionMsg, pException); } } 参考书籍: 《实用J2EE设计模式编程指南》 《WEB服务精髓》 《J2EE 与 BEA WEBLOGIC SERVER》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值