`

Eclipse+JBoss+EJB3消息驱动Bean

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

import java.io.Serializable; 
import java.util.Date; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity
@Table(name="t_date") 
public class DateBean implements Serializable 

    private int id; 
    private Date myDate; 
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    public int getId() 
    { 
        return id; 
    } 
     
    public void setId(int id) 
    { 
        this.id = id; 
    } 
    @Column(name="mydate") 
    public Date getMyDate() 
    { 
        return myDate; 
    } 
    public void setMyDate(Date myDate) 
    { 
        this.myDate = myDate; 
    } 
     

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

import javax.ejb.ActivationConfigProperty; 
import javax.ejb.EJBException; 
import javax.ejb.MessageDriven; 
import javax.jms.Message; 
import javax.jms.MessageListener; 
import javax.jms.ObjectMessage; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import entity.DateBean; 

@MessageDriven( activationConfig =  {         
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), 
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MDBQueue") 
      }) 
public class DateMessageBean implements MessageListener 

    @PersistenceContext(unitName = "myentity1") 
    private EntityManager em; 

    @Override
    public void onMessage(Message message) 
    { 
        try
        { 
            if(message instanceof ObjectMessage) 
            { 

                ObjectMessage objmsg = (ObjectMessage) message; 
                DateBean dateBean = (DateBean) objmsg.getObject(); 
                em.persist(dateBean); 
                System.out.println("成功持久化DateBean对象!"); 
            } 
            else
            { 
                System.out.println("消息类型错误!"); 
            } 
        } 
        catch (Exception e) 
        { 
            throw new EJBException(e); 
        } 

    } 


消息驱动Bean需要使用@MessageDriven进行注释。要注意的是destination属性的值是queue/MDBQueue。JBoss不会自已建立一个Queue对象,因此,需要手工来配置Queue对象。读者可以\server\default\deploy目录中建立一个xxx-service.xml文件,其中xxx可以任意取值,但必须跟“-service”后缀,例如,abc-service.xml。该文件可以放在deploy或其子目录(可以是多层子目录)中。该文件的内容如下:
< xml version="1.0" encoding="UTF-8"?>
< server>
  < mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=MDBQueue">
    < depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManagerdepends>
  < mbean>
< server>
    
要注意的是,元素的name属性值中的name必须是MDBQueue,要与queue/MDBQueue中的/后面的部分一致。如果不进行上面的配置,在启动JBOSS时就会抛出如下的异常:
javax.naming.NameNotFoundException: MDBQueue not bound
也可以将元素放在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
package service; 

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.annotation.Resource; 
import javax.ejb.Stateless; 
import javax.jms.Connection; 
import javax.jms.ConnectionFactory; 
import javax.jms.MessageProducer; 
import javax.jms.ObjectMessage; 
import javax.jms.Queue; 
import javax.jms.Session; 
import javax.persistence.EntityManager; 
import entity.DateBean; 
import entity.Greeting; 

@Stateless
public class GreeterBean implements Greeter 

    @Resource(mappedName = "ConnectionFactory") 
    private ConnectionFactory cf; 
    @Resource(mappedName = "queue/MDBQueue") 
    private Queue queue; 

    @Override
    public String greet(String message) 
    { 
        try
        { 
            DateBean db = new DateBean(); 
            db.setMyDate(new Date()); 
            Connection connection = cf.createConnection(); 
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
            MessageProducer messageProducer = session.createProducer(queue); 
            ObjectMessage objectMessage = session.createObjectMessage(); 
            objectMessage.setObject(db); 
            messageProducer.send(objectMessage); 
            connection.close(); 
            System.out.println("成功发送消息!"); 
        } 
        catch (Exception e) 
        { 
            System.out.println("发送消息失败!"); 
        } 

        return "方法成功返回"; 

    } 

在上面的代码中使用ObjectMessage对象来包装要向消息服务器发送的实体Bean的对象实例。
除了可以在SessionBean中访问消息驱动Bean外,还可以在不同的机器上通过jndi来查找并调用消息驱动Bean,代码如下:
package test; 

import java.util.Date; 
import javax.ejb.EJB; 
import javax.jms.Destination; 
import javax.jms.MessageProducer; 
import javax.jms.ObjectMessage; 
import javax.jms.Queue; 
import javax.jms.QueueConnection; 
import javax.jms.QueueConnectionFactory; 
import javax.jms.QueueSession; 
import javax.jms.TextMessage; 
import javax.naming.InitialContext; 
import entity.DateBean; 

import service.Greeter; 

public class Client 


    public static void main(String[] args) throws Exception 
    { 
        InitialContext ctx = new InitialContext(); 
        QueueConnection connection = null; 
        QueueSession session = null; 
        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory"); 
        connection = factory.createQueueConnection(); 
        session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); 
        Destination destination = (Queue) ctx.lookup("queue/MDBQueue"); 
        MessageProducer messageProducer = session.createProducer(destination); 
        ObjectMessage objectMessage = session.createObjectMessage(); 
        DateBean db = new DateBean(); 
        db.setMyDate(new Date()); 
        objectMessage.setObject(db); 
        messageProducer.send(objectMessage); 
        connection.close(); 
        System.out.println("成功发送消息!"); 
    } 
分享到:
评论

相关推荐

    eclipse + JBoss 5 + EJB3开发指南

    (8):JBoss EJB3(HelloWorld)备忘记 15 摘要: 15 备忘记开始: 16 [1] 安装 jdk 5: 16 [2] 安装 JBoss EJB3: 16 [3] 第一次启动 JBoss: 18 [4] 安装 Eclipse WTP: 18 [5] 安装 JBoss IDE: 18 [6] 使用 ...

    Eclipse+Jboss EJB技术 会话Bean

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

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

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

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

    3. 把该项目导出为EJB格式的jar包到jboss-4.2.1.GA\server\default\deploy\目录 4. 在Eclipse中启动服务器 5. 运行app.Test客户端测试类 使用Eclipse 3.4 Ganymede开发EJB3.0的JavaEE应用比较简化和方便。该示例使用...

    经典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 版本: 第一版 出版社: 电子...

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

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

    eclipse-ejb项目.zip

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

    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:正常下载,...

    EJB HelloWorld

    3用eclipse打包想到或ant打成jar包 在jboss控制台可以看到部署成功 在jmx-console-》jboss-》service=JNDIView -》Operation-》list 可以看到Global JNDI Namespace HelloWorldBean (class: org.jnp.interfaces....

    jboss5 as development源码

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

    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.3. Seam 中的可点击列表:消息示例............................................................................................................................. 27 1.3.1. 理解代码.........................

    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