| |
用service locator 模式实现命名访问
--------------------------------------------------------------------------------
用service locator 模式实现命名访问服务
在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);
}
}
|
|