每个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.c
闽公网安备 35060202000074号