EJB系统控件无法直接用于访问EJB资源,使用者必须继承EJB控件来创建自己的访问控件。一个继承控件只能对应于一个EJB的访问,所以使用者必须针对不同的EJB创建不同的访问控件。
你可以使用下面的步骤来创建自己的控件实现对EJB资源的访问:
创建Java接口,根据目标EJB资源类型的不同选择继承不同的EJB控件类要访问SessionBean类型的EJB资源,Java接口必须继承org.apache.beehive.controls.system.ejb.SessionEJBControl接口。
要访问EntityBean类型的EJB资源,Java接口必须继承org.apache.beehive.controls.system.ejb.EntityEJBControl接口。
用@ControlExtension关键字注释新创建的Java接口,通知解析器这个接口继承了另外的某个控件。 继承目标EJB的Home和Remote接口,这些接口可能是本地的或者是远程的。 使用@EJBHome.jndiName或者@EJBHome.ejbLink注释新创建的Java接口,指定控件如何搜索EJB实例。 如果控件使用jndiName来访问EJB,还需要使用@JNDIContextEnv关键字注释新创建的Java接口,说明控件如何与目标EJB容器实现交互。在本节中,我们将通过简单的例子演示如何使用EJB控件来访问SessionBean。
我们假设需要开发一个简单的SessionBean并且使用EJB控件来访问它。该EJB提供一个简单的Remote方法sayHello,调用sayHello可以返回”Hello World!”字符串。该EJB支持Remote方式访问。
为了说明Beehive并不仅仅局限于WebLogic平台,我们选择JBoss应用服务器作为演示时使用的EJB容器,EJB发布时使用的JNDI名称是“jndi/helloworld”。
接下来的EJB开发、部署和控件访问部分内容也针对JBoss应用服务器。实际情况下,你可能根据不同情况选择其他的J2EE容器比如Websphere、WebLogic、Geronimo、JOnAS等作为EJB容器,请根据下面的提示信息进行适当的调整。
开发SessionBean首先我们来开发提供sayHello业务方法SessionBean,作者使用Eclipse+WTP(Web Tools Platform)插件工具完成开发。
如何开发EJB不是本文的关注点,所以这里只是简单的提供EJB实现对应的代码。开发EJB的学习资料可以在参考资源中找到。
EJB Bean类源代码—HelloWorld.java清单1 ejbsrc/org/vivianj/beehive/controls/examples/ejb/helloworld.java
1. package org.vivianj.beehive.controls.examples.ejb;2. 3. import javax.ejb.*;4. 5. public class HelloWorld6. implements SessionBean7. {8. public void ejbCreate() {9. }10. public String sayHello()11. {12. return “Hello World!”;13. }14. } EJB Remote接口类源代码—HelloWorldRemote.java清单2 ejbsrc/org/vivianj/beehive/controls/examples/ejb/HelloWorldRemote.java
1. package org.vivianj.beehive.controls.examples.ejb;2. 3. import javax.ejb.EJBObject;4. import java.rmi.RemoteException;5. 6. import javax.ejb.*;7. 8. public interface HelloWorldRemote extends EJBObject {9. 10. public String sayHello() throws RemoteException;11. 12. } EJB Home接口类源代码-- HelloWorldHome.java清单3 ejbsrc/org/vivianj/beehive/controls/examples/ejb/HelloWorldHome.java
1. package org.vivianj.beehive.controls.examples.ejb;2. 3. import javax.ejb.CreateException;4. import javax.ejb.EJBHome;5. import javax.ejb.FinderException;6. import java.rmi.RemoteException;7. import java.util.Collection;8. 9. import javax.ejb.*;10. 11. public interface HelloWorldHome extends EJBHome {12. 13. public HelloWorldRemote create() 14. throws CreateException, RemoteException;15. 16. }EJB开发完成后,我们可以将EJB打包成企业应用,然后将生成的企业应用发布到JBoss应用服务器上。
开发EJB控件我们现在来开发一个EJB控件-- HelloWorldSessionEJBControl,通过它我们能够直接访问 1.开发SessionBean 中开发和部署的EJB。
HelloWorldSessionEJBControl通过JBoss提供的org.jnp.interfaces.NamingContextFactory工厂类获取EJB访问的上下文环境。
清单4中是EJB控件的全部源代码。
清单4 src/org/vivianj/beehive/controls/examples/controls/
HelloWorldSessionEJBControl.java
1. package org.vivianj.beehive.controls.examples.controls;2. 3. import org.apache.beehive.controls.api.bean.ControlExtension;4. import org.apache.beehive.controls.system.ejb.SessionEJBControl;5. import org.vivianj.beehive.controls.examples.ejb.helloworldHome;6. import org.vivianj.beehive.controls.examples.ejb.helloworldRemote;7. 8. /**9. * HelloWorldSessionEJBControl 用于封装访问远程JBoss服务器上 10. * SessionBean的操作方法11. */12. @ControlExtension13. @SessionEJBControl.EJBHome(jndiName = “jndi/helloworld”)14. @SessionEJBControl.JNDIContextEnv(15. contextFactory = “org.jnp.interfaces.NamingContextFactory”, 16. providerURL = “jnp://localhost:1099”)17. public interface HelloWorldSessionEJBControl 18. extends SessionEJBControl,19. HelloWorldHome, HelloWorldRemote {20. } EJB控件调用我们可以通过下面的几个步骤,实例化EJB控件并调用它的业务方法。
在Controller中使用声明式控件实例化定义成员变量_ejbControl@Control
HelloWorldSessionEJBControl _ejbControl;
完成控件的业务方法调用在控件的某个Action方法中完成EJB业务方法的调用,这里要注意的是控件的业务方法通常都声明抛出RemoteException,所以调用的时候需要调用try … catch处理。
try { _ejbControl.sayHello(); } catch (Exception e) { e.printStackTrace(); } 移除控件实例,释放EJB引用在控件使用完毕以后,应该调用控件的remove方法,以便释放对于EJB的引用,避免可能出现的服务器性能问题。
try { _ejbControl.remove(); } catch (Exception e) { e.printStackTrace(); } 测试EJB控件一切准备就绪后,启动JBoss服务器,参考《控件入门》中“使用JUnit测试控件”部分的内容,编写单元测试TestCase测试新创建的EJB控件。
从上面的例子中我们可以看到,使用EJB控件访问EJB资源的时候,开发者的工作被大大的简化了。开发者只需要开发一个继承自EJB控件的控件,使用 EJB控件中规定的注释提供访问EJB所需要的一些环境参数,随后便可以使用声明式控件实例化方式完成控件的实例化,通过调用该控件实例的相关业务方法完 成EJB资源的访问。
现在我们来分析一下上面创建的EJB控件-- HelloWorldSessionEJBControl (参见清单4)中的主要代码。
12. @ControlExtension在控件例子的12行,我们通过@ControllerExcention注释来说明接下来声明的这个接口是另外一个控件的扩展。 HelloWorldSessionEJBControl控件继承自SessionEJBControl,所以必须使用在接口定义前使用 ControllerExcention。
13. @SessionEJBControl.EJBHome(jndiName = “jndi/helloworld”)在第13行代码中我们使用@SessionEJBControl.EJBHome关键词和它的jndiName属性来设置我们要访问EJB在目标服务器中发布时使用的jndiName.
14. @SessionEJBControl.JNDIContextEnv( 15. contextFactory = “org.jnp.interfaces.NamingContextFactory”, 16. providerURL = “jnp://localhost:1099”)在第14~16行中我们使用@SessionEJBControl.JNDIContextEnv的contextFactory属性和providerURL来设置目标服务器的JNDI上下文环境工厂和目标服务器的访问地址信息。
17. public interface HelloWorldSessionEJBControl 18. extends SessionEJBControl, 19. HelloWorldHome, HelloWorldRemote {在第17~19行中,我们声明该控件继承了EJB控件SessionEJBControl接口和目标EJB的Home、Remote接口。
前面的两节内容中,我们通过创建访问SessionBean控件的例子,简单的说明了如何通过继承EJB控件快速访问EJB资源的步骤和方法。通过控件访 问Entity Bean的步骤和访问SessionBean的步骤基本一致,只不过继承对象变成了EntityEJBControl,而不再是 SessionEJBControl,请读者参考上面的步骤自己完成。
J2EE架构下,客户端访问EJB多采用jnp协议访问EJB容器的JNDI树,通过查找相应的JNDI对象获取EJB访问实例。EJB控件提供了注释 EJBHome和JNDIContextEnv,其中JNDIContextEnv用于指定访问目标EJB容器上下文环境所需要的参数,EJBHome用 于指定如何在上下文中获取EJB的Home接口。
下面的内容将详细的讲述如何使用EJBHome和JNDIContextEnv两个注释来定制EJB控件。
JNDIContextEnv注释是类级别的注释元素,用于设置EJB继承类访问EJB时所需要使用的JNDI上下文工厂类名、目标服务器的相关必要信息 (访问协议、ip地址、端口等)、访问时需要提供的访问用户名和密码。JNDIContextEnv包括contextFactory、 providerURL、principal、credentials属性。
contextFactory字符串类型的属性,设置访问EJB JNDI上下文环境需要使用工厂类,比如访问JBoss应用服务器上的EJB资源时可以设置contextFactory属性为”org.jnp.interfaces.NamingContextFactory”。
providerURL字符串类型的属性,设置目标EJB容器的相关属性,包括访问JNDI上下文环境使用的协议、目标服务器IP地址、服务端口等,比如访问JBoss容器中ejb时,providerURL可以写成”jnp://localhost:1099”。
principal字符串类型的属性,设置访问EJB时需要提供的安全用户名。
credentials字符串类型的属性,设置访问EJB时需要提供的安全密码。
EJBHome是类级别的注释元素,用于设定获取EJB Home接口的实例,支持的属性包括了jndiName和ejbLink,你可以选择性的使用其中任何一个。
jndiNameString类型,EJB在EJB容器中发布时使用的jndi名称,你也可以使用jndi协议形式的url来设置这个参数。比如你可以使用 jndi/helloworld来设置这个参数,你也可以使用jndi://localhost:7001/jndi/helloworld这样的url 来设置这个参数。
ejbLinkString类型,用于设置与包含的EJB jar文件应用路径相关的目标EJB名,命名的语法是BeanName#EJBJAR,比如HelloWorldHome@HelloWorldEjb.jar。
EJB是J2EE框架中最重要的部分,也是企业应用中最常用的技术之一,然而EJB的客户端编写对于开发者而言不是一件轻松的事情。控件架构中的EJB控 件大大的简化了EJB资源的复杂性、难度,开发者只需要通过简单的继承 org.apache.beehive.controls.system.ejb.SessionEJBControl或者 org.apache.beehive.controls.system.ejb.EntityEJBControl,然后通过提供相应的注释就可以完成 EJB资源的访问。
本文中,作者首先通过简单的例子介绍了EJB控件使用的基本步骤,然后详细的介绍了EJB控件提供的EJBHome和JNDIContextEnv注释以及它们的使用方法。
参考资源
Beehive在线资源:
http://beehive.apache.org/documentation.html
下载资源
本文中例子下载地址:
EJBControlExamples.zip
作者简介肖菁肖菁 是唯J族(www.vivianj.org)创始人,BEA 杭州User Group负责人,自由撰稿人,开源项目BuildFileDesigner(buildfiledesign.sourceforge.net)和V- Security(v-security.sourceforge.net)创始人。