千家信息网最后更新 2024年11月18日如何使用EJB3.0
这篇文章将为大家详细讲解有关如何使用EJB3.0,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
什么是EJB?
一个企业JavaBean (EJB)是一个可重用的,可移植的J2EE组件。 EJB由封装了业务逻辑的多个方法组成。例如,一个EJB可以有包括一个更新客户数据库中数据的方法的业务逻辑。多个远程和本地客户端可以调用这个方法。另外,EJB运行在一个容器里,允许开发者只关注与bean中的业务逻辑而不用考虑象事务支持,安全性和远程对象访问等复杂和容易出错的事情。EJB以POJO或者普通旧的Java对象形式开发,开发者可以用元数据注释来定义容器如何管理这些Bean。
EJB类型
EJB主要有三种类型:会话Bean,实体Bean和消息驱动Bean。会话Bean完成一个清晰的解耦的任务,例如检查客户账户历史记录。实体Bean是一个代表存在于数据库中业务对象的复杂业务实体。消息驱动Bean用于接收异步JMS消息。让我们更详细的认识这些类型。
会话Bean
会话Bean一般代表着业务流程中象"处理订单"这样的动作。会话Bean基于是否维护过度状态分为有状态或者无状态。无状态会话Bean 没有中间状态。它们不保持追踪一个方法调用另一个方法传递的信息。因此一个无状态业务方法的每一次调用都独立于它的前一个调用;例如,税费计算或者转移账款。 当计算税费额的方法被调用时,税费值被计算并返回给调用的方法,没有必要存储调用者为将来调用备用的内部状态。因为它们不维护状态,所以这些Bean是仅仅由容器管理。当客户端请求一个无状态的Bean实例时,它可以接收来自由容器管理的无状态会话Bean实例集中的一个实例。也因为无状态会话Bean能够被共享,所以容器可以维护更少数量的实例来为大量的客户端服务。简单地象该Bean增加元注释@Stateless 来指定一个 Java Bean作为一个无状态会话Bean被部署和管理。
一个有状态的会话Bean维护一个跨越多个方法调用的会话状态;例如在线购物篮应用。当客户开始在线购物时,客户的详细信息从数据库获得。相同的信息对于当客户从购物篮中增加或者移除商品等等操作时被调用的其他方法也是可访问的 。但是因为该状态不是在会话结束,系统崩溃或者网络失败时保留,所以有状态会话Bean是暂时的。当一个客户端请求一个有状态会话Bean实例时,客户端将会得到一个会话实例,该Bean的状态只为给客户端维持。通过向方法增加元注释@Remove来告诉容器当某个方法调用结束一个有状态会话Bean实例应该被移除。会话Bean实例
import javax.ejb.Stateless.*;
/** * A simple stateless session bean implementing the incrementValue() method of the * CalculateEJB interface. */
@Stateless(name="CalculateEJB") public class CalculateEJBBean implements CalculateEJB { int value = 0; public String incrementValue() { value++; return "value incremented by 1"; } }
|
实体Bean
实体Bean是管理持久化数据的一个对象,潜在使用一些相关的Java对象并且可以依靠主键被***识别。通过包括@Entity 元注释来指定一个类是一个实体Bean。实体Bean表示来自数据库的持久化数据,例如客户表中的一个纪录,或者一个员工表中的一个员工记录。实体Bean也可以被多个客户端共享。例如一个员工实体能够被多个计算一个员工每年工资总额或者更新员工地址的客户端使用。实体Bean对象特定变量能够保持持久化。实体Bean中所有没有@Transient 元注释的变量需要考虑持久化。EJB3.0的一个主要特色是创建包含使用元数据注释的对象/关系映射实体Bean的能力。例如,指定实体Bean的empId变量映射到employee表中的EMPNO属性,象下面实例中一样用@Table(name="Employees") 注释这个表的名字和用@Column(name="EMPNO")注释empId变量。另外,EJB3.0中的一个特色是你可以很容易的在开发时测试实体Bean,可以用Oracle Application Server Entity Test Harness在容器外部运行一个实体Bean。
import javax.persistence.*; import java.util.ArrayList; import java.util.Collection;
@Entity @Table(name = "EMPLOYEES") public class Employee implements java.io.Serializable { private int empId; private String eName; private double sal;
@Id @Column(name="EMPNO", primaryKey=true) public int getEmpId() { return empId; }
public void setEmpId(int empId) { this.empId = empId; }
public String getEname() { return eName; }
public void setEname(String eName) { this.eName = eName; }
public double getSal() { return sal; }
public void setSal(double sal) { this.sal = sal; }
public String toString() { StringBuffer buf = new StringBuffer(); buf.append("Class:") .append(this.getClass().getName()).append(" :: ").append(" empId:").append(getEmpId()).append(" ename:").append(getEname()).append("sal:").append(getSal()); return buf.toString(); } }
|
消息驱动Bean
驱动Bean (MDB) 提供了一个实现异步通信比直接使用Java消息服务(JMS)更容易地方法。创建MDB接收异步JMS消息。容器处理为JMS队列和主题所要求加载处理的大部分工作。它向相关的MDB发送所有的消息。一个MDB允许J2EE应用发送异步消息,该应用能处理这些消息。实现javax.jms.MessageListener接口和使用@MessageDriven注释该Bean来指定一个Bean是消息驱动Bean。
消息驱动Bean实例
import javax.ejb.MessageDriven; import javax.ejb.ActivationConfigProperty; import javax.ejb.Inject; import javax.jms.*; import java.util.*; import javax.ejb.TimedObject; import javax.ejb.Timer; import javax.ejb.TimerService; @MessageDriven( activationConfig = { @ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConnectionFactory"), @ActivationConfigProperty(propertyName="destinationName", propertyValue="jms/myTopic"), @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"), @ActivationConfigProperty(propertyName="messageSelector", propertyValue="RECIPIENT = 'MDB'") } )
/** * A simple Message-Driven Bean that listens to the configured JMS Queue or Topic and gets notified via an * invocation of it's onMessage() method when a message has been posted to the Queue or Topic. The bean * prints the contents of the message. */
public class MessageLogger implements MessageListener, TimedObject {
@Inject javax.ejb.MessageDrivenContext mc;
public void onMessage(Message message) { System.out.println("onMessage() - " + message); try { String subject = message.getStringProperty("subject"); String inmessage = message.getStringProperty("message"); System.out.println("Message received\n\tDate: " + new java.util.Date() + "\n\tSubject: " + subject + "\n\tMessage: " + inmessage + "\n"); System.out.println("Creating Timer a single event timer"); TimerService ts = mc.getTimerService(); Timer timer = ts.createTimer(30000, subject); System.out.println("Timer created by MDB at: " + new Date(System.currentTimeMillis()) +" with info: "+subject); } catch (Throwable ex) { ex.printStackTrace(); } }
public void ejbTimeout(Timer timer) { System.out.println("EJB 3.0: Timer with MDB"); System.out.println("ejbTimeout() called at: " + new Date(System.currentTimeMillis())); return; } }
|
使用EJB
客户端是访问Bean的应用程序。虽然没有必要保存在客户层,但是能够作为一个独立的应用,JSP,Servlet,或者另一个EJB。客户端通过Bean的远程或者本地接口访问EJB中的方法,主要取决于客户端和Bean运行在同一个还是不同的JVM中。这些接口定义了Bean中的方法,而由Bean类实际实现这些方法。当一个客户端访问该Bean类中的一个方法时,容器生成Bean的一个代理,被叫做远程对象或者本地对象。远程或者本地对象接收请求,委派它到相应的Bean实例,返回结果给客户端。调用一个Bean中的方法,客户端使用定义在EJB不是描述文件的名字查找到Bean。在以下实例中,客户端使用上下文对象找到命名为"StateLessejb"Bean。
EJB 客户端实例
import javax.naming.Context; import javax.naming.InitialContext; /** * A simple bean client which calls methods on a stateless session bean. */ public class CalculateejbClient { public static void main(String [] args) { Context context = new InitialContext(); CalculateEJB myejb = (CalculateEJB)context.lookup("java:comp/env/ejb/CalculateEJB"); myejb.incrementValue(); } } |
关于"如何使用EJB3.0"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。