• 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 }
    HelloWorldMDB

    注意该类上的注解,它表明了要监听哪个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>
    pom.xml

    二、测试验证

    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 }
    Send Message

    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>
    jboss-ejb3.xml

    然后把HelloWorldQueueMDB类上的那一堆注解全注释掉,再跑下,顺利的话,也同样可以接收消息

    示例源代码下载:mdb-sample.zip

  • 相关阅读:
    Centos搭建PHP5.3.8+Nginx1.0.9+Mysql5.5.17
    初识Mongodb总结
    初识Mongodb之[CURD]PHP版
    Centos搭建Samba
    PHP图像处理(二) GraphicsMagick 安装扩展及使用方法
    Vcastr3.0开源在线flv播放器
    自动更新@version svn版本号信息
    Centos安装Memcache
    MVC演化
    JAVA与.NET的相互调用——TCP/IP相互调用基本架构
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/3562347.html
Copyright © 2020-2023  润新知