ejb3: message drive bean(MDB)示例
上一篇已经知道了JMS的基本操作,今天来看一下ejb3中的一种重要bean:Message Drive Bean(mdb)
如果要不断监听一个队列中的消息,通常我们需要写一个监听程序,这需要一定的开发量,而且如果要实现高并发处理,也不易扩展,而MDB则自动实现了该功能,简单点讲,MDB的应用部署到jboss后,能自动监听目标队列,一旦有消息接收,会触发onMessage事件,开发人员可以在该事件处理中扩展自己的业务逻辑.
一、定义一个MDB
package mdb; import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; import util.LoggerUtil; @MessageDriven(name = "HelloWorldQueueMDB", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/queue/mytest"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class HelloWorldMDB implements MessageListener { @Override
public void onMessage(Message msg) {
TextMessage txtMsg = null;
try {
if (msg instanceof TextMessage) {
txtMsg = (TextMessage) msg;
String msgContent = txtMsg.getText();
LoggerUtil.info("Received Message from queue: " + msgContent);
} else {
LoggerUtil.warning("Message of wrong type: "
+ txtMsg.getClass().getName());
}
} catch (JMSException e) {
throw new RuntimeException(e);
} } }
HelloWorldMDB
注意该类上的注解,它表明了要监听哪个Queue(可以参考上一篇的内容,先在jboss中建好该queue),其它没什么特别的,把它放一个dynamic web中,打成war包部署到jboss上,为演示效果,部署后,先不启动该应用
附:pom.xml文件的内容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>cnblogs</groupId>
<artifactId>helloworld-mdb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>helloworld-mdb</name> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-tools</artifactId>
<version>1.0.7.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<dependency>
<groupId>org.jboss.spec.javax.jms</groupId>
<artifactId>jboss-jms-api_1.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.1_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> </project>
pom.xml
二、测试验证
a) 可以参考上一篇JMS的内容,另建一个常规的project,向该队列发送消息(注意:仅发送,不要接收,否则消息被收走了,MDB就收不到消息了)
package jms; import java.util.Hashtable; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException; public class App { public static void main(String[] args) throws NamingException, JMSException { final String lOOKUP_CONNECTION_FACTORY_NAME = "lookup.connectionfactory.name";
final String lOOKUP_DESTINATION_NAME = "lookup.destination.name"; ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
MessageProducer producer = null;
MessageConsumer consumer = null;
Destination destination = null;
TextMessage message = null;
Context context = null; try {
// 创建上下文(默认会从应用的classpath下加载jndi.properties做为环境参数)
context = new InitialContext(); // 把环境参数取出来,后面会用到
Hashtable<String, String> env = (Hashtable<String, String>) context
.getEnvironment(); // 查找连接工厂
connectionFactory = (ConnectionFactory) context.lookup(env
.get(lOOKUP_CONNECTION_FACTORY_NAME)); // 查找目标队列
destination = (Destination) context.lookup(env
.get(lOOKUP_DESTINATION_NAME)); // 创建连接
connection = connectionFactory.createConnection(
env.get(Context.SECURITY_PRINCIPAL),
env.get(Context.SECURITY_CREDENTIALS)); // 创建会话
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 创建生产者(即发送者)
producer = session.createProducer(destination); // 创建消费者(即接收者)
consumer = session.createConsumer(destination); // 开始连接
connection.start(); // 发送消息 message = session.createTextMessage("HELLO,I AM GLAD TO SEE YOU!"); producer.send(message); System.out.println("发送成功!"); } catch (NamingException e) {
e.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 释放资源
if (context != null) {
context.close();
} if (connection != null) {
connection.close();
} }
} }
Send Message
b) 然后在jboss中,再把该应用启用起来,观察console窗口的输出:
三、xml方式配置MDB
刚才我们是用注解方式来配置MDB的,这种方式不需要xml配置文件,十分方便,但是也有缺点,配置与代码紧耦合,如果以后要修改queue名称,就得改代码,重新编译,所以jboss也提供了xml配置方式
方法:在META-INF(非web项目)或WEB-INF(web项目)放置一个名为jboss-ejb3.xml(这是固定名称,不要修改!)
内容参考下面这样:
<?xml version="1.0" encoding="UTF-8"?>
<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="urn:clustering:1.0"
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
version="3.1" impl-version="2.0">
<enterprise-beans>
<message-driven>
<ejb-name>HelloWorldQueueMDB</ejb-name>
<ejb-class>mdb.HelloWorldMDB</ejb-class>
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destination</activation-config-property-name>
<activation-config-property-value>jms/queue/mytest</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>acknowledgeMode</activation-config-property-name>
<activation-config-property-value>Auto-acknowledge</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<c:clustering>
<ejb-name>DDBasedClusteredSFSB</ejb-name>
<c:clustered>true</c:clustered>
</c:clustering>
</assembly-descriptor>
</jboss:ejb-jar>
jboss-ejb3.xml
然后把HelloWorldQueueMDB类上的那一堆注解全注释掉,再跑下,顺利的话,也同样可以接收消息
示例源代码下载:mdb-sample.zip
ejb3: message drive bean(MDB)示例的更多相关文章
- jboss EAP 6.2 + Message Drive Bean(MDB) 整合IBM Webshpere MQ 7.5
上一篇我们知道了消息驱动Bean的基本用法,实际大型分布式企业应用中,往往会采用高性能的商业Queue产品,比如IBM Webshpere MQ(目前最新版本是7.5 ),下面讲解下如何在Jboss ...
- tomee 第一个 远程调用 Message-driven bean(MDB)
MDB 整体结构 HelloMDB.java package cn.zno; import javax.jms.Connection; import javax.jms.ConnectionFacto ...
- JMS和消息驱动Bean(MDB)
一.说明 本示例使用的ActiveMQ作为消息中间件,服务器为Glassfish,使用JMS发送消息,在MDB接收到消息之后做打印输出. 二.ActiveMQ安装配置 1.安装console war包 ...
- 消息驱动bean(MDB)实例
到眼下为止前面介绍的有关JavaEE的东西都是同步的.也就是说调用者调用某个方法.那么这种方法必须马上运行并返回运行结果. 用官方一些的语言来说就是"client通过业务接口调用一个方法,在 ...
- Spring Bean范围 示例
Spring 该目的是通过默认单身创建的对象 设定Bean范围.由Bean美元Scope财产 Scope取值范围: Singleton:单例 proptotype:非单例 Request:创建该Bea ...
- NetBean 8 创建EJB
一. 介绍 百度了一下关于在NetBean开发环境里创建EJB的教程,没有找到好的例子,2天的调试过程,写下来帮助后人. EJB (Enterprise Java Bean) 是一套高扩展性的开发企业 ...
- EJB3.0 EJB开发消息驱动bean
(7)EJB3.0 EJB开发消息驱动bean JMS 一: Java消息服务(Java Message Service) 二:jms中的消息 消息传递系统的中心就是消息.一条 Message 由三个 ...
- Intellij IDEA 创建消息驱动Bean - 接收JMS消息
除了同步方式的调用之外,有时还需要异步调用,用来处理不需要即时处理的信息,例如短信.邮件等,这需要使用EJB中的独特组件——消息驱动Bean(Message-Driven Bean,MDB),它提供了 ...
- EJB3 阶段总结+一个EJB3案例 (1)
经过一段时时间的学习,对EJB3的相关知识和jboss8的配置有了大概的了解. 网上对EJB的评论很多,基本都是负面的,都表示EJB太过于沉重,不容易维护.但通过这段时间的学习,私下认为,EJB3在某 ...
随机推荐
- JAVA中的注解小结
以下内容参考java编程思想-4,jdk版本为jdk5.0,有点老-_-||| 什么是注解 JAVA SE5引入,也称元数据,可以直接添加到代码中,用来完整描述程序所需的信息,而这些信息是无法用Jav ...
- ADO.Net(三)——数据库操作类
操作数据类 避免代码重用.造对象太多.不能分工开发 利用面向对象的方法,把数据访问的方式优化一下,利用封装类 一般封装成三个类: 1.数据连接类 提供数据连接对象 需要引用命名空间: using Sy ...
- SQL Server 2012实施与管理实战指南(笔记)——Ch5启动SQL Server服务和数据库
5.启动SQL Server服务和数据库 在数据库和服务启动过程中,经常会出现的问题: 1.SQL Server实例无法正常启动 2.系统数据库无法正常启动 3.网络配置失败 4.用户数据库无法启动 ...
- SQL Server 2012中Task是如何调度的?
SQL Server 2012中Task是如何调度的?[原文来自:How It Works: SQL Server 2012 Database Engine Task Scheduling] ...
- 十五天精通WCF——第十一天 如何对wcf进行全程监控
说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做“生命周期”,我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤, ...
- crontab执行不生效-【问题篇】
背景:shell脚本每隔两分钟从数据库取数据库放到脚本所在目录,做好计划任务发现不生效. 解决:脚本中文件路径问题 测试:在/data/test目录下写的脚本,直接在本目录touch以分钟结尾的文件. ...
- 解猜数字(XAXB)
我的想法是:把所有备选答案当做正确答案和猜的数字对比,如果得出XAXB和给出的XAXB相同则保留 代码 ; ; List<string> number = new List<stri ...
- Servlet/JSP-05 Cookie
一. 问题? HTTP协议是一种无状态协议,服务器本身无法识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是独立的.现实业务中服务器有时候需要识别来自同一个浏览器的一系列请求,例如购物车,登录 ...
- DOS命令:IIS安装与卸载
//IIS7完全安装 start /w pkgmgr /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticCont ...
- jasperreports+iReport制作报表笔记
一. 准备工作 1. 下载相关工具:点击此下载相关工具,jasperreports-5.6.0-project.zip中有提供所需的jar包. 二. 安装ant 1. 解压apache-ant-1.9 ...