所有类型EJB的创建都要遵循相同的步骤和原则。
- 创建机制
- 创建代码的限制
- 创建可部署组件
1、创建机制
EJB的开发必须经过如下步骤:
- 设计和定义业务接口,包括解决方案的UML模型到Java的映射。
- 决定采用哪种适合当前任务的bean类型。实体类型、会话类型和消息驱动类型各有优劣。如果选择使用会话bean,还有一个问题就是实施拥有状态的还是无状态的会话bean。如何选择合适类型的bean将在后面的课程小结中详细讨论。
- 根据不同的bean类型决定使用哪些本地接口方法,并为EJB定义本地接口。
- 使用正确的生命周期方法创建(或生成)一个“样板”bean。
- 填充业务方法,创建业务逻辑。
- 填充生命周期方法,控制EJB的创建和销毁并管理EJB状态(如果时可应用的)。
如果EJB类编写正确,其余要做的就是将这些类打包成一个可部署单元。然而,创建bean是有一些限制。
2、创建代码的限制
由于bean生命周期的被管理特性,EJB容器对bean强加了某些限制,包括:
- EJB无法执行输入/输出文件。如果需要将信息或访问文件记入日志,必须查找一种机制。
- 不允许EJB启动线程。所有线程都有容器控制。
- EJB无法调用native method。
- EJB无法使用静态成员变量。
- EJB无法使用GUI,因而不需要使用AWT或IFC组件。
- EJB不能作为监听入口连接的网络服务器。
- EJB不应该创建classloader或为artifact(例如套接字)修改工厂信息。
- EJB不应该从方法返回this。尽管这不是一种严格的限制,但这么做是一个很糟的选择。bean不应该实现与他关联的远程接口。如果EJB从方法返回this,将潜在地给客户端一个到bean而不是EJBObject的直接远程引用。因此,bean应该为到其关联的EJBObject的引用查询自己的EJB环境,然后返回值给调用者。
要查看代码创建时的完整限制清单,请参考EJB2.0规范的24.1.2部分(可在线从http://java.sun.com/products/ejb/docs.html 处获取)
3、创建可部署组件
组件有另外一种定义,即称其为“部署单元”。此类情况下,组建应该
- 包含部署组件需要的所有信息,这些信息要比类的内容更多。这些信息就是前面提到的元数据。
- 以这种方式绑定组件可以方便地传输和部署组件,而不会遗失任何组成部分。
- 因此为EJB创建类和接口后,必须执行以下操作:
[1] 捕获通用的可理解格式的元数据。采用基于XML的部署描述符(DD)形式。
[2]以可部署格式(即JAR文件)将类和部署描述符进行打包。
(1)部署描述符
EJB规范为XML部署描述符文档(可用于存储EJB元数据)定义了一种标准格式。部署描述符的准确格式通常隐藏在代表你操作描述符的工具之后。然而,若要了解EJB如何协同工作、如何提供额外信息和元数据,就很有必要查看一下部署描述符的内容了。
程序清单4.5 Agency Bean EJB部署描述符
1:<?xml version="1.0" encoding="UTF-8"?>
2:
3:<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
4:
5:<ejb-jar>
6: <display-name>Simple</display-name>
7: <enterprise-beans>
8: <session>
9: <display-name>Agency</display-name>
10: <ejb-name>Agency</ejb-name>
11: <home>agency.AgencyHome</home>
12: <remote>agency.Agency</remote>
13: <ejb-class>agency.AgencyBean</ejb-class>
14: <session-type>Stateless</session-type>
15: <transaction-type>Bean</transaction-type>
16: <env-entry>
17: <env-entry-name>AgencyName</env-entry-name>
18: <env-entry-type>java.lang.String</env-entry-type>
19: <env-entry-valeu>Job Agency</env-entry-value>
20: </env-entry>
21: <security-identity>
22: <description></description>
23: <use-caller-identity></use-caller-identity>
24: </security-identity>
25: <resource-ref>
26: <res-ref-name>jdbc/Agency</res-ref-name>
27: <res-type>javax.sql.DataSource</res-type>
28: <res-auth>Container</res-auth>
29: <res-sharing-scope>Shareable</res-sharing-scope>
30: </resource-ref>
31: </session>
32: </enterprise-beans>
33:</ejb-jar>
程序清单4.5中部署描述符的关键部分是:
- 使用<session>标记为Agency EJB的定义划分界限,指明这是一个会话EJB(第8行和31行)
- 在Agency实例中,<ejb-name>标记定义EJB的名字(第10行)
- <home>和<remote>标记本别制定了本地和远程接口的类型(由他们的全限定类文件名定义,第11~12行)。Bean自身的类型有<ejb-class>标记进行定义(第13行)。
- 使用<env-entry>标记在16行和20行之间定义环境条目。这表明一个名为AgencyName的String特性可供bean使用,此特性的值是Job Agency。可通过名字java:comp/env下的JNDI使用部署描述符中定义的环境。在此实例中,通过查询名字java:comp/env/AgencyName来检索求职代理实例的名字。
- 在25~30行之间使用<resource-ref>标记定义一个外部资源。定义jdbc/Agency名下的这个EJB能够使用DataSource。
部署描述符应该被命名为ejb-jar.xml。
(2)企业应用程序
尽管目前已经完成EJB-JAR文件,但要实现某一有效用途还必须将其作为应用程序的一部分。J2EE规定可从组件(Web、EJB和应用程序组件)构造企业应用程序。关键是如何定义应用程序的不同部分之间的关系——即必须有某种方法将不同组合在一起。
这个方法就是必须有一个应用程序自身的描述,描述使用哪个组件、这些组件如何相互关联以及这些组件使用哪些具体资源等。这是应用程序组装者和部署这角色提供的信息。
为向目标J2EE平台提供这些信息,需要使用另一级别的部署描述符——J2EE部署描述符。
J2EE部署描述符提供下列内容:
- 应用程序组件清单;
- 安全角色信息;
- Web组件的根信息。
这些信息存储在一个名为application.xml的XML文件中。所有这些组件JAR文件(例如EJB-JAR)和J2EE部署描述符都被打包在另外一个JAR文件中,这些文件被称为企业归档(EAR)文件,带有一个.ear文件扩展名。当学习范例应用程序的各个组成部分是,会有更为详细的内容介绍J2EE部署描述符。
现在可以部署企业应用程序了么?很不幸,答案是“还差一点”。J2EE部署描述符没有包含如何将应用程序映射到J2EE应用服务器的信息,尤其是:
- 应用服务器在哪个JNDI名字下使用EJB可用。在Agency bean实例中,这意味着需要一个条目映射Agency的bean名字和JNDI名字(在此名字下注册EJB)。例如ejb/Agency。
- 定义的安全角色如何映射到底层安全人员
因此,我们需要另一个基于XML、与应用服务器相关的部署描述符来包含这些信息。此文件包含一些额外的前文描述过的映射信息,同时还包含一些为在环境中顺利进行部署而需要的信息。这类部署描述符也存储在EAR文件中,共部署应用程序时进行访问。
注意:Weblogic81服务器的专用部署描述符称为weblogic-ejb-jar.xml。