帝国软件
  设为首页 加入收藏 关于我们
 
解密帝国网站管理系统
栏 目:
 
您的位置:首页 > 技术文档 > JAVA编程 >
运用反射实现ejb动态委派
作者:未知 发布时间:2005-03-12 来源:JSP天空网
每个bean可能会有很多方法,一般我们通过一个delegate来调用sessionbean中的方法,而非直接调用sessionbean,delegate中只是简单的对每个相对应的sessionbean的public方法的简单封装,在调用的时候省去了每次对home的查找和ejb对象的create,但是可能我们的bean会有很多方法,如果每个bean都写这样一个delegate,这样工作量就会很大,而且也不便于以后系统的移植,比如说,原来使用ejb实现,现在要改用jdo直接操作数据库,而通过运用java的reflect技术,就能较好地实现这些要求。首先,定义了一个FacadeDelegate的抽象类,用来实现对sessionbean的home的查找,代码如下:

import javax.ejb.*;

import testejb.util.common.*;

import testejb.util.resource.*;



public abstract class FacadeDelegate{

private static String type = Resource.RemoteType;

public FacadeDelegate() {

}

public EJBHome getHome(String jindiName,Class className)

{

EJBHome home = null;

ServerLocatorAdapter adapter = ServerLocatorAdapter.getInstance();

try

{

home = (EJBHome)adapter.getHome(type, jindiName, className);

}

catch(Exception e)

{

System.err.println(e.getMessage() + jindiName + className.toString());

}

return home;

}



}

其中ServerLocatorAdapter是一个用来根据是local还是remote调用ejb对象而通过不同的方法查找home的类,如果type为local则调用LocalServerLocate中的方法,如果type为remote则调用RemoteServerLocate中的方法,获得home。代码如下:

import java.util.*;

import java.lang.reflect.*;



import testejb.util.resource.*;



public class ServerLocatorAdapter {

private Map cache;//用来缓存home

private static ServerLocatorAdapter me;

public static ServerLocatorAdapter getInstance()

{

if(me == null)

me = new ServerLocatorAdapter();

return me;

}



//取得home

public Object getHome(String type,String jndiHomeName,Class className) throws Exception

{

Object home = null;

if(cache.containsKey(jndiHomeName))

return cache.get(jndiHomeName);

if(Resource.LocalType.equals(type))

{

home = getLocalHome(jndiHomeName,className);

cache.put(jndiHomeName,home);

return home;

}

if(Resource.RemoteType.equals(type))

{

home = getRemoteHome(jndiHomeName,className);

cache.put(jndiHomeName,home);

return home;

}



return home;

}

//取得local home

private Object getLocalHome(String jndiHomeName,Class className) throws Exception

{

Class myClass = Class.forName(Resource.LocalClass);

// Resource. LocalClass =”testejb.util.common. LocalServerLocator

Method method = myClass.getMethod(Resource.LocalConstractMethod,null);

// Resource. LocalConstractMethod =” getInstance”

LocalServerLocator local = null;

local = (LocalServerLocator)method.invoke(myClass,null);

return local.getLocalHome(jndiHomeName,className);





}

//取得remote home

private Object getRemoteHome(String jndiHomeName,Class className) throws Exception

{

Class myClass = Class.forName(Resource.RemoteClass);

// Resource.RemoteClass =”testejb.util.common.RemoteServerLocator”

Method method = myClass.getMethod(Resource.RemoteConstractMethod,null);

// Resource.RemoteConstractMethod=” getInstance”

RemoteServerLocator remote = null;

remote = (RemoteServerLocator)method.invoke(myClass,null);

return remote.getHome(jndiHomeName,className);



}

private ServerLocatorAdapter() {

// 为cache提供线程安全的保证

cache = Collections.synchronizedMap(new HashMap());

}



}

其中Resource为资源类,其中通过对配置文件的读取,取得一些指定的配置信息。

RemoteServerLocator和LocalServerLocator是两个根据不同的调用方式取得home借口的具体实现类,代码如下:

LocalServerLocator:

import javax.naming.*;

import javax.rmi.PortableRemoteObject;

import java.util.*;

import javax.ejb.*;





public class LocalServerLocator {



private Context ic;

private Map cache;//缓存home

private static LocalServerLocator me;



public static LocalServerLocator getInstance()

{

if(me == null)

{

try

{

me = new LocalServerLocator();

}

catch(Exception e)

{

System.err.println(e.getCause());

System.err.println(e.getMessage());

}



}

return me;

}



public EJBLocalHome getLocalHome(String jndiHomeName, Class className) throws Exception {

EJBLocalHome home = null;

try {

if (cache.containsKey(jndiHomeName)) {

home = (EJBLocalHome) cache.get(jndiHomeName);

} else {

Object objref = ic.lookup(jndiHomeName);

home = (EJBLocalHome) objref;

cache.put(jndiHomeName, home);

}

} catch (NamingException ne) {

System.err.println(jndiHomeName);

throw ne;

} catch (Exception e) {

throw e;

}

return home;

}





private LocalServerLocator() throws Exception{

try

{

ic = new InitialContext();

// 为cache提供线程安全的保证

cache = Collections.synchronizedMap(new HashMap());

}

catch(NamingException ne)

{

throw ne;

}

catch(Exception e)

{

throw e;

}





}



}



RemoteServerLocator

import javax.naming.*;

import javax.rmi.PortableRemoteObject;

import java.util.*;

import javax.ejb.*;





public class RemoteServerLocator{

private Context ic;

private Map cache;

private static RemoteServerLocator me;



public static RemoteServerLocator getInstance()

{

if(me == null)

{

try

{

me = new RemoteServerLocator();

}

catch(Exception e)

{

System.err.println(e.getMessage());

}

}

return me;

}



public EJBHome getHome(String jndiHomeName, Class className) throws Exception {

EJBHome home = null;

try {

if (cache.containsKey(jndiHomeName)) {

home = (EJBHome) cache.get(jndiHomeName);

} else {

Object objref = ic.lookup(jndiHomeName);

Object obj = PortableRemoteObject.narrow(objref, className);

home = (EJBHome) obj;

cache.put(jndiHomeName, home);

}

} catch (NamingException ne) {

System.err.println(jndiHomeName);

throw ne;

} catch (Exception e) {

throw e;

}

return home;

}



private RemoteServerLocator() throws Exception{

try {

ic = getInitialContext();

// 为cache提供线程安全的保证

cache = Collections.synchronizedMap(new HashMap());

} catch (NamingException ne) {

throw ne;

} catch (Exception e) {

throw e;

}



}



private javax.naming.Context getInitialContext() throws NamingException {

java.util.Hashtable JNDIParm = new java.util.Hashtable();

JNDIParm.put(Context.PROVIDER_URL, "your server address");

JNDIParm.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");

return new InitialContext(JNDIParm);

}



}



对上面这些调用机制有个了解之后,下面就是来具体的实现动态委派了,再此定义了一个FacadeDelegateImp类,继承了FacadeDelegate类。先看一下代码,然后对此作解释,这样比较清楚一些

import testejb.delegate.common.*;

import javax.ejb.*;

import java.lang.reflect.*;

import java.util.*;





public class FacadeDelegateImp extends FacadeDelegate {

private static FacadeDelegateImp me;

private Map cache;

private HashMap methodMap;

private Object object;



public static FacadeDelegateImp getInstance()

{

if(me == null)

me = new FacadeDelegateImp();

return me;

}

//init方法是在调用invoke之前对要调用的sessionbean进行初始化

public void init(String jindiName, String className) {

EJBHome home = null;

if(cache.containsKey(jindiName))

home = (EJBHome)cache.get(jindiName);

else

{

try

{

home = super.getHome(jindiName, Class.forName(className));//调用父类的的方法取得home

}

catch(Exception e)

{

System.err.println(e.getMessage());

}

cache.put(jindiName,className);

}

try

{

object = home.getClass().getMethod("create", null).invoke(home, null);//调用home的//create方法,取得ejbObject

methodMap = new HashMap();

//将ejbObject中所有的方法存入methodMap中

Method[] aryMethod = object.getClass().getMethods();

if(aryMethod != null && aryMethod.length > 0)

{

for (int i = 0; i < aryMethod.length; i++) {

methodMap.put(aryMethod[i].getName(), aryMethod[i]);

}

}

}

catch(Exception e)

{

System.err.println(e.getMessage());

}

}

//此init方法是对一般java类初始化

public void init(String className,Object[] args)

{

boolean flage = false;

if(cache.get(className) != null)

object = cache.get(className);

else

{

try {

Class myClass = Class.forName(className);

if (args != null && args.length > 0) {

Class[] type = new Class[args.length];

for (int i = 0; i < type.length; i++) {

type[i] = args[i].getClass();

}

Constructor constructor = myClass.getConstructor(type);

object = constructor.newInstance(args);

cache.put(className, object);

}

else {

object = myClass.newInstance();

cache.put(className, object);

}

}

catch (Exception e) {

System.err.println(e.getMessage());

}

}

Method[] methods = object.getClass().getMethods();

methodMap = new HashMap();

for(int i = 0; i< methods.length; i++)

methodMap.put(methods[i].getName(),methods[i]);

}



public Object invoke(String method, Object[] args,String jindiName, String className)

{

if("init".equals(method))

{

this.init(jindiName, className);

return null;

}

if(methodMap == null)

this.init(jindiName, className);

Method tmpMethod = (Method)methodMap.get(method);

if(tmpMethod != null)

{

try

{

return tmpMethod.invoke(object, args);

}

catch(Exception e)

{

System.err.println(e.getMessage());

}

}

return null;

}



public Object invoke(String method, Object[] args, String className)

{

if("init".equals(method))

{

this.init(className,args);

return null;

}

if(methodMap == null)

System.err.println("not init");

Method tmpMethod = (Method)methodMap.get(method);

if(tmpMethod != null)

{

try

{

return tmpMethod.invoke(object, args);

}

catch(Exception e)

{

System.err.println(e.getMessage());

}

}

return null;

}







private FacadeDelegateImp() {

cache = Collections.synchronizedMap(new HashMap());

}





}

来自:CSDN 作者:skyjiang
参考文章:EJB 最佳实践:动态委派 作者:O&acute;Reilly and Associates
  
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
无相关信息

   栏目导行
  PHP编程
  ASP编程
  ASP.NET编程
  JAVA编程
   站点最新
·致合作伙伴的欢迎信
·媒体报道
·帝国软件合作伙伴计划协议
·放眼未来 帝国近期将有重大举措!
·PHPWind6.3.2版通行证发布
·帝国备份王2008版正式发布
·帝国备份王2008版发布
·phpcms2007转帝国CMS5.0程序发布
·dedecms5.1转帝国CMS5.0程序发布
·帝国网站管理系统V5.0商业购买说明
   类别最新
·谈谈JDBC
·JDBC专题介绍
·JDBC接口技术
·利用weblogic的POOL(连接池)连接
·Jsp中调用Oracle存储过程的小例子
·JSP数据库操作例程
·JSP数据库连接大全
·用连接池提高Servlet访问数据库的效
·一种简单JDBC连接池的实现
·数据库连接池Java实现小结
 
关于帝国 | 广告服务 | 联系我们 | 程序开发 | 网站地图 | 留言板 帝国网站管理系统