ejb3: message drive bean(MDB)示例
时间:2022-04-24
本文章向大家介绍ejb3: message drive bean(MDB)示例,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
上一篇已经知道了JMS的基本操作,今天来看一下ejb3中的一种重要bean:Message Drive Bean(mdb)
如果要不断监听一个队列中的消息,通常我们需要写一个监听程序,这需要一定的开发量,而且如果要实现高并发处理,也不易扩展,而MDB则自动实现了该功能,简单点讲,MDB的应用部署到jboss后,能自动监听目标队列,一旦有消息接收,会触发onMessage事件,开发人员可以在该事件处理中扩展自己的业务逻辑.
一、定义一个MDB
1 package mdb;
2
3
4
5 import javax.ejb.ActivationConfigProperty;
6 import javax.ejb.MessageDriven;
7 import javax.jms.JMSException;
8 import javax.jms.Message;
9 import javax.jms.MessageListener;
10 import javax.jms.TextMessage;
11
12 import util.LoggerUtil;
13
14 @MessageDriven(name = "HelloWorldQueueMDB", activationConfig = {
15 @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
16 @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/queue/mytest"),
17 @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
18 public class HelloWorldMDB implements MessageListener {
19
20 @Override
21 public void onMessage(Message msg) {
22 TextMessage txtMsg = null;
23 try {
24 if (msg instanceof TextMessage) {
25 txtMsg = (TextMessage) msg;
26 String msgContent = txtMsg.getText();
27 LoggerUtil.info("Received Message from queue: " + msgContent);
28 } else {
29 LoggerUtil.warning("Message of wrong type: "
30 + txtMsg.getClass().getName());
31 }
32 } catch (JMSException e) {
33 throw new RuntimeException(e);
34 }
35
36 }
37
38 }
注意该类上的注解,它表明了要监听哪个Queue(可以参考上一篇的内容,先在jboss中建好该queue),其它没什么特别的,把它放一个dynamic web中,打成war包部署到jboss上,为演示效果,部署后,先不启动该应用
附:pom.xml文件的内容
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>cnblogs</groupId>
8 <artifactId>helloworld-mdb</artifactId>
9 <version>0.0.1-SNAPSHOT</version>
10 <packaging>war</packaging>
11 <name>helloworld-mdb</name>
12
13 <dependencyManagement>
14 <dependencies>
15 <dependency>
16 <groupId>org.jboss.bom</groupId>
17 <artifactId>jboss-javaee-6.0-with-tools</artifactId>
18 <version>1.0.7.Final</version>
19 <type>pom</type>
20 <scope>import</scope>
21 </dependency>
22 </dependencies>
23 </dependencyManagement>
24
25 <dependencies>
26 <dependency>
27 <groupId>org.jboss.spec.javax.jms</groupId>
28 <artifactId>jboss-jms-api_1.1_spec</artifactId>
29 <scope>provided</scope>
30 </dependency>
31 <dependency>
32 <groupId>org.jboss.spec.javax.ejb</groupId>
33 <artifactId>jboss-ejb-api_3.1_spec</artifactId>
34 <scope>provided</scope>
35 </dependency>
36 </dependencies>
37
38 </project>
二、测试验证
a) 可以参考上一篇JMS的内容,另建一个常规的project,向该队列发送消息(注意:仅发送,不要接收,否则消息被收走了,MDB就收不到消息了)
1 package jms;
2
3
4 import java.util.Hashtable;
5
6 import javax.jms.Connection;
7 import javax.jms.ConnectionFactory;
8 import javax.jms.Destination;
9 import javax.jms.JMSException;
10 import javax.jms.MessageConsumer;
11 import javax.jms.MessageProducer;
12 import javax.jms.Session;
13 import javax.jms.TextMessage;
14 import javax.naming.Context;
15 import javax.naming.InitialContext;
16 import javax.naming.NamingException;
17
18 public class App {
19
20 public static void main(String[] args) throws NamingException, JMSException {
21
22 final String lOOKUP_CONNECTION_FACTORY_NAME = "lookup.connectionfactory.name";
23 final String lOOKUP_DESTINATION_NAME = "lookup.destination.name";
24
25 ConnectionFactory connectionFactory = null;
26 Connection connection = null;
27 Session session = null;
28 MessageProducer producer = null;
29 MessageConsumer consumer = null;
30 Destination destination = null;
31 TextMessage message = null;
32 Context context = null;
33
34 try {
35 // 创建上下文(默认会从应用的classpath下加载jndi.properties做为环境参数)
36 context = new InitialContext();
37
38 // 把环境参数取出来,后面会用到
39 Hashtable<String, String> env = (Hashtable<String, String>) context
40 .getEnvironment();
41
42 // 查找连接工厂
43 connectionFactory = (ConnectionFactory) context.lookup(env
44 .get(lOOKUP_CONNECTION_FACTORY_NAME));
45
46 // 查找目标队列
47 destination = (Destination) context.lookup(env
48 .get(lOOKUP_DESTINATION_NAME));
49
50 // 创建连接
51 connection = connectionFactory.createConnection(
52 env.get(Context.SECURITY_PRINCIPAL),
53 env.get(Context.SECURITY_CREDENTIALS));
54
55 // 创建会话
56 session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
57
58 // 创建生产者(即发送者)
59 producer = session.createProducer(destination);
60
61 // 创建消费者(即接收者)
62 consumer = session.createConsumer(destination);
63
64 // 开始连接
65 connection.start();
66
67 // 发送消息
68
69 message = session.createTextMessage("HELLO,I AM GLAD TO SEE YOU!");
70
71 producer.send(message);
72
73 System.out.println("发送成功!");
74
75
76
77 } catch (NamingException e) {
78 e.printStackTrace();
79 } catch (JMSException e) {
80 e.printStackTrace();
81 } finally {
82 // 释放资源
83 if (context != null) {
84 context.close();
85 }
86
87 if (connection != null) {
88 connection.close();
89 }
90
91 }
92 }
93
94 }
b) 然后在jboss中,再把该应用启用起来,观察console窗口的输出:
三、xml方式配置MDB
刚才我们是用注解方式来配置MDB的,这种方式不需要xml配置文件,十分方便,但是也有缺点,配置与代码紧耦合,如果以后要修改queue名称,就得改代码,重新编译,所以jboss也提供了xml配置方式 方法:在META-INF(非web项目)或WEB-INF(web项目)放置一个名为jboss-ejb3.xml(这是固定名称,不要修改!) 内容参考下面这样:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
3 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:c="urn:clustering:1.0"
5 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"
6 version="3.1" impl-version="2.0">
7 <enterprise-beans>
8 <message-driven>
9 <ejb-name>HelloWorldQueueMDB</ejb-name>
10 <ejb-class>mdb.HelloWorldMDB</ejb-class>
11 <activation-config>
12 <activation-config-property>
13 <activation-config-property-name>destinationType</activation-config-property-name>
14 <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
15 </activation-config-property>
16 <activation-config-property>
17 <activation-config-property-name>destination</activation-config-property-name>
18 <activation-config-property-value>jms/queue/mytest</activation-config-property-value>
19 </activation-config-property>
20 <activation-config-property>
21 <activation-config-property-name>acknowledgeMode</activation-config-property-name>
22 <activation-config-property-value>Auto-acknowledge</activation-config-property-value>
23 </activation-config-property>
24 </activation-config>
25 </message-driven>
26 </enterprise-beans>
27 <assembly-descriptor>
28 <c:clustering>
29 <ejb-name>DDBasedClusteredSFSB</ejb-name>
30 <c:clustered>true</c:clustered>
31 </c:clustering>
32 </assembly-descriptor>
33 </jboss:ejb-jar>
然后把HelloWorldQueueMDB类上的那一堆注解全注释掉,再跑下,顺利的话,也同样可以接收消息
示例源代码下载:mdb-sample.zip
- 设计模式专题(十八) ——桥接模式
- 设计模式专题(十九) ——命令模式
- Thinking in SQL系列之:数据挖掘K均值聚类算法与城市分级
- 设计模式专题(二十) ——职责链模式
- 设计模式专题(二十一) ——中介者模式
- 设计模式专题(二十二) ——享元模式
- 设计模式专题(二十三) ——解释器模式
- Thinking in SQL系列之数据挖掘C4.5决策树算法
- 设计模式专题(二十四) ——访问者模式
- PHP实用功能——modern PHP读书笔记(一)
- ModernPHP读书笔记(二) ——PHP开发标准
- iBatis.Net(6):Data Map(深入)
- iBatis.Net(5):Data Map(了解)
- ModernPHP读书笔记(三)——PHP的良好实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 腾讯云智能语音小程序插件实现实时语音识别
- 我还在生产玩 JDK7,JDK 15 却要来了!|新特性尝鲜
- 36个助你成为专家需要掌握的JavaScript概念
- Bulehero 蠕虫病毒安全分析报告
- 一句话加速grep近30倍
- 正道的光!这有个用TensorFlow做的小黄图过滤器
- Bytom侧链Vapor源码浅析-节点出块过程
- Logstash: 启动监控及集中管理
- 渗透测试中文件上传技巧
- PHP常见过WAF webshell及最简单检测方法
- 基于PhantomJS的动态爬虫引擎
- XSS Cheat Sheet
- 免费代理池的实现与优化
- 基于Django和clean-blog前端框架的博客系统
- 应急响应笔记之Linux篇