用SERVICE LOCATOR 模式實現命名訪問 (轉)

worldblog發表於2007-08-16
用SERVICE LOCATOR 模式實現命名訪問 (轉)[@more@]

用SERVICE LOCATOR 實現命名訪問服務

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

在B/S開發中, 我們經常要用到名稱服務,如JNDI,XMLNS等。名稱服務隨不同廠家而不同。每次需要獲得名稱服務時,需要適當的名稱環境資訊,然後查詢服務,重複查詢的成本很高。

 

此外,在永續性中,要求將所有的服務訪問都包裝到中,開發人員不需要知道名稱服務後面的平臺()型別,及任何資訊或地址。在一個大型產品間存在多個和多個資料來源連線時(我們目前只有一個寫死的資料來源GL)需要一個類來實現統一的訪問管理。

 

因此,這就要求我們對這些訪問進行封裝隔離。這時我們就可以利用SERVICE LOCATOR模式。

 

 

我們將利用一個service.properties來管理所有的命名服務。例子程式碼實現了EJB本地,資料來源的訪問。

格式如下:

DEFAULTDS=webgl

NTCLASSREF=NTHome.class

 

把它儲存在CLASSPATH引用的路徑裡。

 

 

Package  com.learn;

 

import .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..PortableRemote;

import java..Connection;

import java.sql.SQLException;

import javax.sql.Data;

 

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 getConn(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);

  }

 

}

 

 

參考書籍:

  《實用設計模式指南》

    《WEB服務精髓》

  《J2EE 與 BEA SERVER》

 

 

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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-962676/,如需轉載,請註明出處,否則將追究法律責任。

相關文章