Each bean may have many ways, usually we call the method in the sessionbean through a delegate, rather than directly calling SessionBean, delegate is just a simple package for each corresponding sessionBean's public method, when calling Every time you look for home, you may have a lot of ways, but you may have a lot of methods. If each bean writes such a delegate, this workload will be large, and it is not convenient for future system Transplantation, for example, the original use of EJB implementation, now you have to use JDO to directly operate the database, and by using Java's Reflect technology, these requirements can be achieved. First, define a Facadedelegate abstract class that implements the lookup of the HOME of SessionBean, the code is as follows:
Import javax.ejb. *;
Import testerjb.util.common. *;
Import Testejb.util.Resource. *;
Public Abstract Class Facadedelegate {
Private static string type = resource.remottype;
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.toTString ());
}
Return home;
}
}
Where ServerLocatorAdapter is a class that looks up the Home by different methods based on whether or trans. code show as below:
Import java.util. *;
Import java.lang.reflect. *;
Import Testejb.util.Resource. *;
Public class serverlocatoradapter {
Private map cache; // Used to cache Home
Private Static ServerLocatorAdapter ME;
Public Static ServerLocatorAdapter getInstance ()
{
IF (me == null)
ME = New ServerLocatorAdapter ();
Return ME;
}
// get home
Public Object Gethome (String Type, String Jndihomename, Class ClassName) Throws Exception
{
Object Home = NULL;
IF (cache.containame))
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;
}
// Get 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);
}
// get 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 () {
/ / Provide thread security for Cache
Cache = collections.synchronizedmap (new hashmap ());
}
}
The resource is the resource class, which acquires some specified configuration information by reading the configuration file.
RemoteServerLocator and LocalServerLocator are two specific implementations of the home excuse based on different calls, the code is as follows:
LocalServerLocator:
Import javax.naming. *;
Import javax.rmi.portableremoteObject;
Import java.util. *;
Import javax.ejb. *;
Public class localserverLocator {
Private context IC;
Private map cache; // Cache HomePrivate 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) {
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 ();
/ / Provide thread security for 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 remoteSerLocator {
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) {
Home = (ejbhome) cache.get (jndihomeename);
} 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 ();
/ / Provide thread security for 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 Jiorm = 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);
}
}
After the above call mechanism has a understanding, the following is the specific implementation dynamic delegation, and then define a FacadEdelegateImp class, inheriting the FacadeElegate class. Let's take a look at the code first, then explain this, this is more clear
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 method;
Private Object Object;
Public Static FacadedelegateImp GetInstance ()
{
IF (me == null)
ME = new facadedelegateImp ();
Return ME;
}
// init method is to initialize the sessionBean to be called before invoking invoke
Public void init (string jindiname, string classname) {
Ejbhome home = null;
IF (cache.containskey (jindina))
HOME = (ejbhome) cache.get (jindiname);
Else
{
Try
{
Home = super.gethome (jindiname, class.forname); // Method to call the parent class get home
}
Catch (Exception E)
{
System.err.println (E.GetMessage ());
}
Cache.PUT (Jindiname, ClassName);
}
Try
{
Object = home.getClass (). getMethod ("create", null) .invoke (home, null); // Call Home // CREATE method, get EJBOBJECT
Methodmap = new hashmap ();
// Put all the methods in the EJBOBJECT in MethodMap
Method [] Arymethod = Object.getClass (). GetMethods ();
IF (Arymethod! = null && arymethod.length> 0)
{
For (INT i = 0; i MethodMap.Put (Arymethod [i] .getname (), Arymethod [i]); } } } Catch (Exception E) { System.err.println (E.GetMessage ()); } } // This init method is initialized for general Java classes 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 [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 MethodMap.Put (Methods [i] .getname (), Methods [i]); } Public Object Invoke (String Method, Object [] Args, String Jindiname, String ClassName { IF ("init" .equals (normal)) { 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 (normal)) { THISINIT (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 ()); } } Reference article: EJB best practices: Dynamic delegate Author: O'Reilly and Associates This is the first time I first published a technical article, and I also understand the EJB. If there is anything wrong, please advise.