原作者: Shashank Tiwari
来源:Javaworld
译者:TKD-恋冰
原文: http://www.javaworld.com/javaworld/jw-08-2006/jw-0814-ejb.html
企业JavaBeans简化了企业bean架构,同时提供了一些更强大的特性。新规范补充支持了Java 5介绍的元数据注释工具以及Hibernate和TopLink这些工具的持久化和对象关系映射的最佳实践,和在一些轻量级Java框架如Spring中十分流行的依赖注入(Dependency Injection)模式。
本文讨论了把用EJB 2.1或更早版本的规范写的应用程序移植到基于EJB 3.0架构的一些可行的移植策略。我们会从设计和执行两方面来评价这些移植方案。本文并不打算详尽地描述每一种移植策略。阅读完这篇文章后,你应该能够根据自己的实际情况,选择一种最适合自己的方法把旧的EJB编码移植到新的规范。
本文假定你已经熟悉了企业bean,Java 5,和对象关系映射的特性及概念。
EJB 2.1到EJB 3.0:有哪些变化?
为了能给本文讨论的这些可行的移植方式提供一个上下文联系,我会从讨论新规范中每种不同的bean类型与以前不同的变化开始,然后再简单地贯穿相关的多种bean类型。
会话(Session) bean
列表1,描述了EJB 2.1规范定义有状态session bean的一个例子。
表 1.基于EJB 2.1的银行服务的有状态session bean
public
interface
BankingService
extends
EJBObject
...
{
public void deposit(int accountId, float amount) throws RemoteException;
public void withdraw(int accountId, float amount)throws RemoteException;
public float getBalance(int accountId) throws RemoteException;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public void doServiceLogout() throws RemoteException;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
interface
BankingServiceHome
extends
EJBHome
...
{
public BankingService create() throws CreateException, RemoteException;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
BankingServiceEJB
implements
SessionBean
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void deposit(int accountId, float amount) throws RemoteException ...{
//Business logic to deposit the specified amount and update the balance
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void withdraw(int accountId, float amount)throws RemoteException ...{
//Business logic to withdraw the desired amount and update the balance
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public float getBalance(int accountId) throws RemoteException ...{
//Business logic to get the current balance
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void doServiceLogout() throws RemoteException ...{
//Service completion and logout logic
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void ejbCreate()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void ejbActivate()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void ejbPassivate()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void ejbRemove()...{}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void setSessionContext(SessionContext context)...{}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
在EJB 3.0规范中,一个session bean只需要定义一个业务接口和一个bean行为类。Home接口已经被移除了。业务接口就是常规的Java接口,有时也叫作POJI,或者纯Java接口(plain-old Java interface)。业务接口不需要扩展EJBObject或EJBLocalObject接口;如果需要,它可以通过描绘业务领域模型的接口层次来定义。
Bean
行为类就是常规的
Java
类,有时也叫作
POJO
,或者叫纯
Java
对象(
plain-old Java object
)。它不用实现
EnterpriseBean
类型。部署描述符中的声明和配置
可以借助元数据注释工具通过
Java
编码来定义。此外,大多数配置都提供了默认值,因此最大程度的减小了
bean
详细配置的必要条件。在新规范下,你可以不用任何
ejb-jar.xml
等部署描述符就能部署
session beans
,尽管它们依然被保留,并且依然可以被使用,如果开发人员相比注释模型更愿意用它们。
当EJB 3.0 session bean
实现了Web service
的时,方法作为
Web service
操作被
WebMethod
描述符注释。
作为
Web service
终端提供服务的
session bean
被注释为
WebService
。
表
2
展示了
EJB 3.0
规范的先前的例子中的有状态
session bean
。
EJB 2.1和一些更早版本的规范里,对于每一个会话 bean来讲,两个接口——home和local(或者说是remote,business)接口——和bean行为类是必须的。Home接口要求必须扩展EJBHome或者EJBLocalHome接口,而且要声明生命周期方法,比如create()。Local,或者说是remote, business接口要求必须扩展EJBObject或EJBLocalObject接口,而且要声名业务方法。Bean行为类本身是EnterpriseBean类型,作为session bean的情况下,扩展了SessionBean子接口。Bean类必须提供其中回调方法的实现,这样容器可以在适当的生命周期事件发生时触发它们。此外,bean中一些受争议的元素, 包括事务和安全定义,还有它们是有状态还是无状态的,都定义在联合部署描述符中。
消息驱动bean
在
EJB 2.1
中,消息驱动
bean
的类实现了
MessageDrivenBean
接口和消息监听接口。回调方法在
bean
类和容器中实现,当特定事件发生时调用相应的方法。
Message-driven
消息驱动
beans
向来都与
home
和
remote
、
local
接口这些概念无关。
在EJB 3.0中,MessageDriven注释被用来标记和说明一个消息驱动bean。部署描述符同样可以用来指定一个bean为消息驱动的。因此,bean类不被要求实现MessageDrivenBean接口。消息驱动bean的业务接口就是消息监听接口,它同那些从bean接口处接受到的信息类型吻合。在Java消息服务中,javax.jms.MessageListener是消息监听接口或者业务接口。Bean类需要实现消息监听接口或者用MessageDriven注释去注释它。
新的规范支持回调方法(PostConstruct和PreDestroy),为连接资源提供了依赖注入模式(Dependency Injection),还允许为消息驱动bean定义拦截方法。