`
1028826685
  • 浏览: 919915 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类

Ejb消息驱动bean使用

阅读更多

接下来对Ejb中的消息驱动bean做一个简单使用总结:

首先我们需要对消息的目标地址在jboss中做一个配置(资料)
开始JMS编程前,我们需要先配置消息到达的目标地址(Destination),因为只有目标地址存在了,我们才能发送消息到这个地址。由于每个应用服务器关于目标地址的配置方式都有所不同,下面以jboss为例,配置一个queue类型的目标地址。
-黑色字体配置不用修改
<?xml version="1.0" encoding="UTF-8"?>
<server> 
  <mbean code=“org.jboss.mq.server.jmx.Queue”
//foshanshop是目标地址名称         name="jboss.mq.destination:service=Queue,name=foshanshop">
// queue/foshanshop指定   foshanshop的JNDI名称
<attribute name="JNDIName">queue/foshanshop</attribute>  
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
  </mbean>
</server>
Jboss使用一个XML文件配置队列地址,文件的取名格式应遵守*-service.xml
<attribute name="JNDIName">属性指定了该目标地址的全局JNDI名称。如果你不指定JNDIName属性,jboss会为你生成一个默认的全局JNDI,其名称由“queue”+“/”+目标地址名称组成。另外在任何队列或主题被部署之前,应用服务器必须先部署Destination Manager Mbean,所以我们通过<depends>节点声明这一依赖。


配置如下:

文件取名:jms-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<server> 
  <mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=testQueue">
<attribute name="JNDIName">queue/testQueue</attribute>  
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
  </mbean>
   <mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=testTopic">
<attribute name="JNDIName">topic/testTopic</attribute>  
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
  </mbean>
</server>

然后发布到jboss 目录\jboss-4.2.3.GA\server\default\deploy

接下来编写消息发送端:
1、TopicSender.java(使用topic)
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//得到一个JNDI初始化上下文(Context)
InitialContext context=new InitialContext();
// 根据上下文查找一个连接工厂 TopicConnectionFactory 。
//该连接工厂是由JMS提供的,不需我们自己创建,每个厂商都为它绑定了一个全局JNDI,我们通过它的全局JNDI便可获取它
TopicConnectionFactory  factory=(TopicConnectionFactory)context.lookup("TopicConnectionFactory");
//从连接工厂得到一个连接 QueueConnection
TopicConnection connection=factory.createTopicConnection();
//QueueSession.AUTO_ACKNOWLEDGE消息确认类型 ---〉自动确认 建立不需要事务的并且能自动确认消息已接收的会话。
TopicSession session=connection.createTopicSession(false,TopicSession.AUTO_ACKNOWLEDGE);
//查找目标地址:
Destination destination=(Destination)context.lookup("topic/testTopic");
//根据session创建消息生产者和消息
MessageProducer producer=session.createProducer(destination);
TextMessage message=session.createTextMessage("这是Topic发送消息");
//发送消息
producer.send(message);


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2、使用queue
QueueSender.java

try {
//得到一个JNDI初始化上下文(Context)
InitialContext context=new InitialContext();
// 根据上下文查找一个连接工厂 QueueConnectionFactory 。
//该连接工厂是由JMS提供的,不需我们自己创建,每个厂商都为它绑定了一个全局JNDI,我们通过它的全局JNDI便可获取它
QueueConnectionFactory  factory=(QueueConnectionFactory )context.lookup("QueueConnectionFactory");
//从连接工厂得到一个连接 QueueConnection
QueueConnection connection=factory.createQueueConnection();
//QueueSession.AUTO_ACKNOWLEDGE消息确认类型 ---〉自动确认 建立不需要事务的并且能自动确认消息已接收的会话。
QueueSession session=connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
//查找目标地址:
Destination destination=(Destination)context.lookup("queue/testQueue");
//根据session创建消息生产者和消息
MessageProducer producer=session.createProducer(destination);
TextMessage message=session.createTextMessage("这是queue发送消息");
//发送消息
producer.send(message);


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

再接下来是编写消息接受端:
1、topic接收端
@MessageDriven(activationConfig =
{
  @ActivationConfigProperty(propertyName="destinationType",
    propertyValue="javax.jms.Topic"),
  @ActivationConfigProperty(propertyName="destination",
    propertyValue="topic/testTopic"),
  @ActivationConfigProperty(propertyName="acknowledgeMode",
    propertyValue="Auto-acknowledge")
})

public class TopicMDB implements MessageListener {

@Override
public void onMessage(Message message) {
TextMessage msg=(TextMessage)message;
try {
System.out.println("Topic:"+msg.getText());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
2、queue接受端:
@MessageDriven(activationConfig =
{
  @ActivationConfigProperty(propertyName="destinationType",
    propertyValue="javax.jms.Queue"),
  @ActivationConfigProperty(propertyName="destination",
    propertyValue="queue/testQueue"),
  @ActivationConfigProperty(propertyName="acknowledgeMode",
    propertyValue="Auto-acknowledge")
})

public class QueueMDB implements MessageListener {

@Override
public void onMessage(Message message) {
TextMessage msg=(TextMessage)message;
try {
System.out.println(msg.getText());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

然后打包、编译 使用build.xml 在项目路径下新建build.xml

<?xml version="1.0"?>

<!-- ======================================================================= -->
<!-- EJB3 HelloWorld build file                                                       -->
<!-- ======================================================================= -->

<project name="EjbJMSBean" default="ejbjar" basedir="..">

<property environment="env" />
<property name="app.dir" value="${basedir}\EjbJMSBean" /><!--EjbJMSBean是项目名称-->
<property name="src.dir" value="${app.dir}\src" />
<property name="jboss.home" value="${env.JBOSS_HOME}" />
<property name="jboss.server.config" value="default" />
<property name="build.dir" value="${app.dir}\build" />
<property name="build.classes.dir" value="${build.dir}\classes" />

<!-- Build classpath -->
<path id="build.classpath">
<fileset dir="${jboss.home}\client">
<include name="*.jar" />
</fileset>
<pathelement location="${build.classes.dir}" />
</path>

<!-- =================================================================== -->
<!-- Prepares the build directory                                        -->
<!-- =================================================================== -->
<target name="prepare" depends="clean">
<mkdir dir="${build.dir}" />
<mkdir dir="${build.classes.dir}" />
</target>

<!-- =================================================================== -->
<!-- Compiles the source code                                            -->
<!-- =================================================================== -->
<target name="compile" depends="prepare" description="编绎">
<!--includes筛选哪些包下的类被编译-->
<javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on" deprecation="on" optimize="off" includes="com/**">
<classpath refid="build.classpath" />
</javac>
</target>

<target name="ejbjar" depends="compile" description="创建EJB发布包">
<jar jarfile="${app.dir}\EjbJMSBean.jar">
<fileset dir="${build.classes.dir}">
<include name="com/**/*.class" />
</fileset>
<!--包含这个persistence.xml文件-->
<!--<metainf dir="${src.dir}\META-INF"></metainf>-->
</jar>
</target>

<target name="deploy" depends="ejbjar">
<copy file="${app.dir}\EjbJMSBean.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy" />
</target>

<!-- =================================================================== -->
<!-- Cleans up generated stuff                                           -->
<!-- =================================================================== -->
<target name="clean">
<delete dir="${build.dir}" />
<delete file="${jboss.home}\server\${jboss.server.config}\deploy\EjbJMSBean.jar" />
</target>

</project>

然后打包、编译 执行TopicSender和QueueSender

参考资料:

消息传递系统的中心就是消息。一条 Message 由三个部分组成:
头(header),属性(property)和主体(body)。

消息有下面几种类型,他们都是派生自 Message 接口。
StreamMessage:一种主体中包含 Java 基元值流的消息。其填充和读取均按顺序进行。
MapMessage:一种主体中包含一组名-值对的消息。没有定义条目顺序。
TextMessage:一种主体中包含 Java 字符串的消息(例如,XML 消息)。
ObjectMessage:一种主体中包含序列化 Java 对象的消息。
BytesMessage:一种主体中包含连续字节流的消息。
JMS 支持两种消息传递模型:点对点(point-to-point,简称 PTP)和发布/订阅(publish/subscribe,简称 pub/sub)。这两种消息传递模型非常相似,但有以下区别:

PTP 消息传递模型规定了一条消息只能传递给一个接收方。 采用javax.jms.Queue 表示。
Pub/sub 消息传递模型允许一条消息传递给多个接收方。采用javax.jms.Topic表示

这两种模型都通过扩展公用基类来实现。例如:javax.jms.Queue 和javax.jms.Topic 都扩展自javax.jms.Destination 类。

消息发送:
一般发送消息有以下步骤:
(1) 得到一个JNDI初始化上下文(Context)
InitialContext ctx = new InitialContext();
(2) 根据上下文查找一个连接工厂 QueueConnectionFactory 。该连接工厂是由JMS提供的,不需我们自己创建,每个厂商都为它绑定了一个全局JNDI,我们通过它的全局JNDI便可获取它;
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");
(3) 从连接工厂得到一个连接 QueueConnection
conn = factory.createQueueConnection();
(4) 通过连接来建立一个会话(Session);
session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
这句代码意思是:建立不需要事务的并且能自动确认消息已接收的会话。
(5) 查找目标地址:
例子对应代码:Destination destination = (Destination ) ctx.lookup("queue/foshanshop");
(6) 根据会话以及目标地址来建立消息生产者MessageProducer (QueueSender和TopicPublisher都扩展自MessageProducer接口)
例子对应代码:
MessageProducer producer = session.createProducer(destination);
TextMessage msg = session.createTextMessage("您好,这是我的第一个消息驱动Bean");
producer.send(msg);
producer.close();
session.close();
con.close();

采用消息驱动Bean (Message Driven Bean)接收消息:

消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件。它和无状态Session Bean一样也使用了实例池技术,容器可以使用一定数量的bean实例并发处理成百上千个JMS消息。正因为MDB具有处理大量并发消息的能力,所以非常适合应用在一些消息网关产品。如果一个业务执行的时间很长,而执行结果无需实时向用户反馈时,也很适合使用MDB。如订单成功后给用户发送一封电子邮件或发送一条短信等。

一个MDB通常要实现MessageListener接口,该接口定义了onMessage()方法。Bean通过它来处理收到的JMS消息。
package javax.jms;
public interface MessageListener {
    public void onMessage(Message message);
}

当容器检测到bean守候的目标地址有消息到达时,容器调用onMessage()方法,将消息作为参数传入MDB。MDB在onMessage()中决定如何处理该消息。你可以使用注释指定MDB监听哪一个目标地址(Destination)。当MDB部署时,容器将读取其中的配置信息。
分享到:
评论

相关推荐

    EJB消息驱动bean Demo

    网上看的一个视频教程里的一个Demo,EJB消息驱动bean Demo。

    ejb 消息驱动Bean例子

    ejb 消息驱动Bean例子.有Queue,Topic

    JavaEE5学习笔记06-EJB之消息驱动Bean总结

    EJB之消息驱动Bean的总结。ejb 消息驱动Bean j2ee jms java

    消息驱动bean EJB 3.0

    消息驱动bean EJB3.0。sender

    ejb2.0消息驱动bean的开发(JBOSS4.0.4.GA 环境)

    NULL 博文链接:https://8366.iteye.com/blog/502114

    EJB2和EJB3 消息驱动bean

    介绍EJB2和EJB3

    EJB 3.0消息驱动Bean(p-to-p and Topic)

    许多初学者拜求的EJB知识点: @MessageDriven( activationConfig ={ @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Topic"), @ActivationConfigProperty(property...

    MDB 消息驱动Bean

    虽然MDB负责处理消息,但是由运行MDB的EJB容器负责处理服务(事务、安全、资源、并发、消息确认,等等),使bean开发者把精力集中在处理消息的业务逻辑上。传统的JMS应用程序必须定制地编写一部分这些服务。MDB在...

    Jboss下开发ejb应用之一消息驱动bean的应用

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

    Message-Driven Bean EJB实例源代码

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

    ejb3.0第11讲 --开发消息驱动bean

    NULL 博文链接:https://8366.iteye.com/blog/413863

    精通EJB第三版

    第2篇重点关注EJB编程的具体内容和过程,其中,研究了如何开发如下三种EJB组件:会话Bean、实体Bean和消息驱动Bean。具体内容包括开发各种EJB组件的基础知识(结合开发实例)、组件生命周期的详细阐述;第3篇是本书最为令...

    ejb.zip_单身会话bean

    java ee 6 ejb的一些实例: 包括 有状态会话bean 无状态会话bean 单身会话bean 消息驱动bean 实例

    EJB3.0部署消息驱动Bean抛javax.naming.NameNotFoundException异常

    主要为大家详细介绍了EJB3.0部署消息驱动Bean抛javax.naming.NameNotFoundException异常,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    JAva EJB购物网站订单处理模块实例.rar

    一个JAva EJB购物网站订单处理模块实例,一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener,onMessage函数...

    精通EJB3.0 中文版 3/3

    第二部分重点关注EJB编程的具体内容和过程,向开发者展示了如何使用会话Bean、将会话Bean发布为Web服务、消息驱动Bean;第三部分专注于高级EJB专题;第四部分是附录,收集了EJB组件技术相关的其他内容。

    精通EJB3.0 中文版 1/3

    第二部分重点关注EJB编程的具体内容和过程,向开发者展示了如何使用会话Bean、将会话Bean发布为Web服务、消息驱动Bean;第三部分专注于高级EJB专题;第四部分是附录,收集了EJB组件技术相关的其他内容。

    EJB 3.0从入门到精通

    全书共分16章,内容依次包含了Java EE概述、EJB基础、搭建EJB环境、会话bean、持久化实体、持久化实体管理器、对象关系映射、JPQL查询、消息驱动bean、事务、提高EJB 3.0性能、从Web层访问EJB 3和EJB安全、EJB和Web...

Global site tag (gtag.js) - Google Analytics