用SERVICE LOCATOR 模式实现命名访问 (转)

本文介绍如何使用SERVICELOCATOR设计模式实现对EJB和数据源的统一命名访问管理。通过缓存技术和配置文件,该模式简化了服务定位过程,提高了应用的灵活性与效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用SERVICE LOCATOR 模式实现命名访问 (转)[@more@]

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

 XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

在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》

 

 

请大家指教:lisong@anyi.com.cn


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-962676/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-962676/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值