`
haierboos
  • 浏览: 438540 次
文章分类
社区版块
存档分类
最新评论

eclipse + JBoss 5 + EJB3开发指南(14):消息驱动Bean

 
阅读更多

本文为原创,如需转载,请注明作者和出处,谢谢!

在前面的文章中给出的SessionBean的例子都是同步调用SessionBean方法的,也就是说,只有当方法中的代码都执行完,才能返回到客户 端。但在某些情况下,由于SessionBean方法的执行时间比较长,这就需要异步地调用该方法,否则客户端就需要等待比较长的时间。要实现异步调用, 就需要使用本要讲的消息驱动Bean。消息驱动Bean的基本原理是客户端向消息服务器发送一条消息后,消息服务器会将该消息保存在消息队列中。在这时消 息服务器中的某个消费者(读取并处理消息的对象)会读取该消息,并进行处理。发送消息的客户端被称为消息生产者。
本文给出的消息驱动Bean的例子的基本功能是客户端向消息服务器发送一条消息(该消息实际上是一个实体Bean的对象实例),然后消息消费者读取这条消息后,将消息中的实体Bean持久化。实现消息驱动Bean的步骤如下:

一、实现实体Bean

Code:
  1. packageentity;
  2. importjava.io.Serializable;
  3. importjava.util.Date;
  4. importjavax.persistence.Column;
  5. importjavax.persistence.Entity;
  6. importjavax.persistence.GeneratedValue;
  7. importjavax.persistence.GenerationType;
  8. importjavax.persistence.Id;
  9. importjavax.persistence.Table;
  10. @Entity
  11. @Table(name="t_date")
  12. publicclassDateBeanimplementsSerializable
  13. {
  14. privateintid;
  15. privateDatemyDate;
  16. @Id
  17. @GeneratedValue(strategy=GenerationType.IDENTITY)
  18. publicintgetId()
  19. {
  20. returnid;
  21. }
  22. publicvoidsetId(intid)
  23. {
  24. this.id=id;
  25. }
  26. @Column(name="mydate")
  27. publicDategetMyDate()
  28. {
  29. returnmyDate;
  30. }
  31. publicvoidsetMyDate(DatemyDate)
  32. {
  33. this.myDate=myDate;
  34. }
  35. }

二、编写消息驱动Bean

消息驱动Bean必须实现MessageListener接口,当该消息驱动Bean接收到一个消息后,EJB容器就会调用MessageListener接口的onMessage方法来理该消息。消息驱动Bean的代码如下:

Code:
  1. packageservice;
  2. importjavax.ejb.ActivationConfigProperty;
  3. importjavax.ejb.EJBException;
  4. importjavax.ejb.MessageDriven;
  5. importjavax.jms.Message;
  6. importjavax.jms.MessageListener;
  7. importjavax.jms.ObjectMessage;
  8. importjavax.persistence.EntityManager;
  9. importjavax.persistence.PersistenceContext;
  10. importentity.DateBean;
  11. @MessageDriven(activationConfig={
  12. @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
  13. @ActivationConfigProperty(propertyName="destination",propertyValue="queue/MDBQueue")
  14. })
  15. publicclassDateMessageBeanimplementsMessageListener
  16. {
  17. @PersistenceContext(unitName="myentity1")
  18. privateEntityManagerem;
  19. @Override
  20. publicvoidonMessage(Messagemessage)
  21. {
  22. try
  23. {
  24. if(messageinstanceofObjectMessage)
  25. {
  26. ObjectMessageobjmsg=(ObjectMessage)message;
  27. DateBeandateBean=(DateBean)objmsg.getObject();
  28. em.persist(dateBean);
  29. System.out.println("成功持久化DateBean对象!");
  30. }
  31. else
  32. {
  33. System.out.println("消息类型错误!");
  34. }
  35. }
  36. catch(Exceptione)
  37. {
  38. thrownewEJBException(e);
  39. }
  40. }
  41. }

消息驱动Bean需要使用

@MessageDriven进行注释。要注意的是destination属性的值是queue/MDBQueue。 JBoss不会自已建立一个Queue对象,因此,需要手工来配置Queue对象。读者可以<JBoss5.x安装目录>/server/ default/deploy目录中建立一个xxx-service.xml文件,其中xxx可以任意取值,但必须跟“-service”后缀,例如, abc-service.xml。该文件可以放在deploy或其子目录(可以是多层子目录)中。该文件的内容如下:

Code:
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <server>
  3. <mbeancode="org.jboss.mq.server.jmx.Queue"name="jboss.mq.destination:service=Queue,name=MDBQueue">
  4. <dependsoptional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
  5. </mbean>
  6. </server>

要注意的是,<mbean>元素的name属性值中的name必须是MDBQueue,要与queue/MDBQueue中的/后面的部分一致。如果不进行上面的配置,在启动JBOSS时就会抛出如下的异常:

javax.naming.NameNotFoundException: MDBQueue not bound

也可以将<mbean>元素放在deploy目录中的其他以-service.xml结尾的文件中。
如果不设置destination属性的值,在启动JBoss是会抛出如下的异常:

org.jboss.deployers.spi.DeploymentException: Required config property RequiredConfigPropertyMetaData@174098f[name=destination descriptions=[DescriptionMetaData@4ca30b[language=zh]]] for messagingType 'javax.jms.MessageListener' not found in activation config [ActivationConfigProperty(destinationType=javax.jms.Queue), ActivationConfigProperty(connectionFactoryJndiName=MyQueueConnectionFactory), ActivationConfigProperty(destinationName=MyRequestQueue)] ra=jboss.jca:service=RARDeployment,name='jms-ra.rar'
... ...

三、编写调用消息驱动Bean的SessionBean

Code:
  1. packageservice;
  2. importjava.util.ArrayList;
  3. importjava.util.Date;
  4. importjava.util.List;
  5. importjavax.annotation.Resource;
  6. importjavax.ejb.Stateless;
  7. importjavax.jms.Connection;
  8. importjavax.jms.ConnectionFactory;
  9. importjavax.jms.MessageProducer;
  10. importjavax.jms.ObjectMessage;
  11. importjavax.jms.Queue;
  12. importjavax.jms.Session;
  13. importjavax.persistence.EntityManager;
  14. importentity.DateBean;
  15. importentity.Greeting;
  16. @Stateless
  17. publicclassGreeterBeanimplementsGreeter
  18. {
  19. @Resource(mappedName="ConnectionFactory")
  20. privateConnectionFactorycf;
  21. @Resource(mappedName="queue/MDBQueue")
  22. privateQueuequeue;
  23. @Override
  24. publicStringgreet(Stringmessage)
  25. {
  26. try
  27. {
  28. DateBeandb=newDateBean();
  29. db.setMyDate(newDate());
  30. Connectionconnection=cf.createConnection();
  31. Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
  32. MessageProducermessageProducer=session.createProducer(queue);
  33. ObjectMessageobjectMessage=session.createObjectMessage();
  34. objectMessage.setObject(db);
  35. messageProducer.send(objectMessage);
  36. connection.close();
  37. System.out.println("成功发送消息!");
  38. }
  39. catch(Exceptione)
  40. {
  41. System.out.println("发送消息失败!");
  42. }
  43. return"方法成功返回";
  44. }
  45. }

在上面的代码中使用ObjectMessage对象来包装要向消息服务器发送的实体Bean的对象实例。

除了可以在SessionBean中访问消息驱动Bean外,还可以在不同的机器上通过jndi来查找并调用消息驱动Bean,代码如下::

Code:
  1. packagetest;
  2. importjava.util.Date;
  3. importjavax.ejb.EJB;
  4. importjavax.jms.Destination;
  5. importjavax.jms.MessageProducer;
  6. importjavax.jms.ObjectMessage;
  7. importjavax.jms.Queue;
  8. importjavax.jms.QueueConnection;
  9. importjavax.jms.QueueConnectionFactory;
  10. importjavax.jms.QueueSession;
  11. importjavax.jms.TextMessage;
  12. importjavax.naming.InitialContext;
  13. importentity.DateBean;
  14. importservice.Greeter;
  15. publicclassClient
  16. {
  17. publicstaticvoidmain(String[]args)throwsException
  18. {
  19. InitialContextctx=newInitialContext();
  20. QueueConnectionconnection=null;
  21. QueueSessionsession=null;
  22. QueueConnectionFactoryfactory=(QueueConnectionFactory)ctx.lookup("ConnectionFactory");
  23. connection=factory.createQueueConnection();
  24. session=connection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
  25. Destinationdestination=(Queue)ctx.lookup("queue/MDBQueue");
  26. MessageProducermessageProducer=session.createProducer(destination);
  27. ObjectMessageobjectMessage=session.createObjectMessage();
  28. DateBeandb=newDateBean();
  29. db.setMyDate(newDate());
  30. objectMessage.setObject(db);
  31. messageProducer.send(objectMessage);
  32. connection.close();
  33. System.out.println("成功发送消息!");
  34. }
  35. }
分享到:
评论

相关推荐

    eclipse + JBoss 5 + EJB3开发指南

    二、开发无状态Session Bean 3 三、编写客户端程序 5 (2):编写有状态的SessionBean 7 (3):使用Session Bean的本地接口 9 (4):Session Bean中的注释方法 11 (5):使用配置文件发布Session Bean 12 (6):...

    Eclipse+Jboss EJB技术 会话Bean

    广东工业大学Java EE Web编程技术课程实验,使用JBoss,实现EJB技术中的会话Bean,简单的Helloworld。

    Jboss下开发ejb应用之一会话bean的应用

    NULL 博文链接:https://fruitking.iteye.com/blog/562868

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    中文名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 原名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 作者: 李刚 资源格式: PDF 版本: 第一版 出版社: 电子...

    使用JBoss 4.2书写EJB3.0无状态会话Bean + JPA + MySql 5.0的Hello World Java EE应用

    本示例是对上一个资源“演示EJB3.0 + JPA + MySQL5.0 + C3P0连接池技术实战编程(Top-Down的XP开发方式)”的简化版本--主要是使用Eclipse 3.4 Ganymede版本来开发EJB3.0中间件与JPA持久层的实战应用。 使用步骤: ...

    传智播客 EJB3.0PPT 完整版 黎明活

    本资源为PPT,配套视频为: ... 11_开发消息驱动bea 12_开发EJB容器模型的WEB服务 附录01_EJB3基本概念及发展前景 附录02_EJB3.0推荐教程 附录03_EJB3的运行环境 如果需要配套视频,请给本人私信。

    jboss-as-7.1.1.Final

    EJB3.1 JBoss7.0.2 EclipseJuno-helloworld实现 2013-01-06 02:59:54 分类: Java EJB3.1 JBoss7.1 Eclipse3.7---helloworld实现 一、环境配置: JDK:正常配置 Eclipse:正常下载,解压(V3.7) JBoss:正常下载,...

    eclipse-ejb项目.zip

    使用的是eclipse创建ejb项目,并使用wildfly(jboss也可以)进行有状态/无状态sessionbean的部署

    jboss5 as development源码

    jboss5 as developemnt是一本很好的书,基本上包括了从entitybean,sessionbean,messagedrivenbean,managedbean的开发。 从ejb工程,到jsf2.0工程,很好的示例,手把手交的。底层连接数据库,开发工具是eclipse ...

    EJB HelloWorld

    EJB的编写方法 1定义一个业务方法接口 public interface HelloWorld { public String SayHello(String...5.用ant或eclipse,把客户端文件打成war包,发布到jboss上 6.输入http://localhost:8080/EJBTest/Test.jsp访问

    jee7_development_wildfly

    Java EE 7 技术: Eclipse Mars + JBoss AS插件JBoss Cli Projeto票务机构: Maven(commódulos) EJB Singleton,无状态,Statefull电子客户端EJB 锁定/写入和并发管理(ConcurrencyManagementType.BEAN) ...

    第一个JPA演示程序

    环境:Window XP Professional, JDK 1.6, Eclipse 3.3 Europa, JBoss 4.2.1, Mysql 5.0 理由:持久层技术从EJB 2.0的实体bean开始,相继出现JDO, Hibernate, iBats等技术,到今天统一的标准JPA出现。因为JPA是一种...

    JBoss Seam 工作原理、seam和hibernate的范例、RESTFul的seam、seam-gen起步、seam组件、配置组件、jsf,jboss、标签、PDF、注解等等

    1.1.1. 在JBoss AS 上运行示例..................................................................................................................................14 1.1.2. 在Tomcat 服务器上运行示例..........

    JAVA上百实例源码以及开源项目

     Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式  //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在...

    JAVA上百实例源码以及开源项目源代码

     Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式  //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在...

    javaee登陆页面源码-lab2:实验室2

    Bean,实现以下功能: 操作用户(录入人员)登陆后,显示本次登陆的次数和上一次登陆的时间; 操作用户登录后,可进行校友的检索、修改、删除、统计等功能; 5分钟如果没有操作,则自动登出系统; 操作用户退出时,...

Global site tag (gtag.js) - Google Analytics