EJB 消息驱动bean 的开发

[b]//-----------------------JMS 消息服务 java message service[/b]

java消息服务 java messae service 简称 JMS ,用于访问企业消息系统的中立的API,说白了就是一组API.
企业消息系统可以协助应用软件通过网络进行消息交互.

JMS(编程)简单概括为应用程序A发送一条消息到消息的服务器的某个目的Destination,然后消息服务把消息发送给应用程序B,因为应用程序A和应用程序B,没有直接的代码关联.所以两者实现了解耦.


[b]一个message由三个部分组成[/b]

头部 heand , 属性 (property) , 主体 body

消息类型 都派生自Message接口
StreamMessage:一种主体中包含Java元值流的信息,其填充和读取均按顺序进行,

MapMessage:主体包含 组名----值对.没有定义条目顺序

TextMessage: 包含java字符串的信息 例如 XML信息

ObjectMessage:主体包含序列化Java对象的信息

BytesMessage:连续字节流的消息

[b]
消息的传递模型[/b]

传递模型:
点对点 :point-to-point PTP

发布/订阅: publish/subscribe 简称 PUB/SUB

两种区别如下:

PTP: 规定了一条消息只能传递给一个接受方,目标类型采用javax.jms.Queue 表示

PUB/SUB: 允许 一条消息传递给多个接受方,目标类型采用java.jms.Topic表示

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



[b]开始开发 --> 配置目标队列地址 -->开发消息发送类--->消息接受类[/b]

jboss 5.0 是需要个*-service.xml这个一个xml文件来配置目标队列地址.
编写好后,拷贝到E:\jboss-6.0.0.Final\server\default\deploy 这就发布了

<!--
<attribute name="JNDIName">属性制定了目标地址的全局JNDI名称,
默认全局JNDI名称(如果不制定JNDIName属性)
jboss会为你生成一个默认全局JNDI名称有 "queue/" +目标地址的名称组成

使用之前都必须<depends> 部署应用该服务器DestinationManager -->

<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=jmsQueue">
<attribute name="JNDIName">queue/jmsQueue</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=jmsTopic">
<attribute name="JNDIName">topic/jmsTopic</attribute>
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>

--> 经过上面发布好后 就可以在jmx-console就可以看到了
http://localhost:8989/jmx-console/jboss.mq.destination 中可以看到刚配置JNDI名称

jboss 6.0 就不需要了,在
E:\jboss-6.0.0.Final\server\default\deploy\hornetq\hornetq-jms.xml 只需要配置一个 queue topic 这个两个标签实体

<queue name="DLQ">
<entry name="/queue/DLQ"/>
</queue>

<queue name="ExpiryQueue">
<entry name="/queue/ExpiryQueue"/>
</queue>

<topic name="testTopic">
<entry name="/topic/topicA"/>
</topic>


--> 经过上面发布好后 就可以在jmx-console就可以看到了
http://localhost:8989/jmx-console/org.hornetq


[img]http://dl.iteye.com/upload/attachment/0080/9245/2019f177-2ec6-31c8-b529-2fa12a288403.jpg[/img]

开发 PTP 消息发送对象类

package com.sh.app;

import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
public class QueueSender {
public static void main(String [] args){
try {
//初始化JNDI上下文
InitialContext ctx=new InitialContext();
//根据上下文查找连接工厂该工厂有JMS提供,不需要我们自己创建,每个厂商都为他绑定了一个全局的JDNI,通过他就可以获取
QueueConnectionFactory factory=(QueueConnectionFactory)ctx.lookup("ConnectionFactory");
//注意 jboss5.0 为 ctx.lookup("QueueConnectionFactory");

//ConnectionFactory cf = (ConnectionFactory) ctx.lookup("ConnectionFactory");
QueueConnection conn=factory.createQueueConnection();
//根据连接得到会话
QueueSession session=conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
//获取目标地址
Destination destination=(Destination)ctx.lookup("/queue/DLQ");
//获取消息的发送者
MessageProducer producer=session.createProducer(destination);
producer.send(session.createTextMessage("你好,JMS我来了,Queue!"));
session.close();
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


开发PUB/SUB 消息发送对象

package com.sh.app;

import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.QueueSession;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.naming.InitialContext;

public class TopicSender {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//初始化JNDI上下文
InitialContext ctx=new InitialContext();
//根据上下文查找连接工厂该工厂有JMS提供,不需要我们自己创建,每个厂商都为他绑定了一个全局的JDNI,通过他就可以获取
TopicConnectionFactory factory=(TopicConnectionFactory)ctx.lookup("ConnectionFactory");
//注意 jboss5.0 为 ctx.lookup("TopicConnectionFactory");

//ConnectionFactory cf = (ConnectionFactory) ctx.lookup("ConnectionFactory"); // jboss6.0
TopicConnection conn=factory.createTopicConnection();
//根据连接得到会话
TopicSession session=conn.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
//获取目标地址
Destination destination=(Destination)ctx.lookup("/topic/topicA");
//获取消息的发送者
MessageProducer producer=session.createProducer(destination);
producer.send(session.createTextMessage("你好,JMS我来了,Topic"));
session.close();
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


//注意 实现 MessageListener 这个监听接口
开发 queue消息驱动bean 去读取消息 (一当被部署到jboss服务器中就会去读取是否有queue类型的消息)

package com.sh.message;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(activationConfig={
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Queue"
),
@ActivationConfigProperty(
propertyName="destination",
propertyValue="/queue/DLQ"
)
})
//jboss 6.0 目标地址类型有"/" 开头
//jboss 5.0 没有 "/" 默认为 "queue/地址名称" 地址名称==*-sercie.xml中配置的
public class MessageDrivenBean implements MessageListener {

@Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
try {
//消息发送者是什么类型就转换成什么类型
TextMessage msg=(TextMessage)message;
System.out.println(msg.getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}



开发 Topic消息驱动bean 去读取消息 (需要监听先存在,然后发送的消息才会被监听到.)


//第一个 topic 消息
package com.sh.message;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(activationConfig={
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Topic"
),
@ActivationConfigProperty(
propertyName="destination",
propertyValue="/topic/topicA"
)
})
public class ReceiveBean implements MessageListener {

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

}


//第二个类
package com.sh.message;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(activationConfig={
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Topic"
),
@ActivationConfigProperty(
propertyName="destination",
propertyValue="/topic/topicA"
)
})
public class ReceiveOtherBean implements MessageListener {

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

}


---jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099



--Ant 文件 build

<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================================
2013-2-25 下午1:53:33

project
description

Bin
====================================================================== -->
<project name="MessageDrivenBean" basedir=".">
<description>
description
</description>
<!-- 设置项目原目录 -->
<property name="src.dir" value="${basedir}\src" />
<!-- 获取环境变量 -->
<property environment="env"/>
<property name="jboss.home" value="${env.JBOSS_HOME}"/>
<property name="jboss.server.config" value="default"/>
<property name="build.dir" value="${basedir}\build"/>

<!-- 引入 jboss client 下的 所有jar -->
<path id="build.classpath">
<fileset dir="${jboss.home}\client">
<include name="*.jar"/>
</fileset>
<!-- 讲编译过后的路径加入到 path中去 方便 接口和实现的引用 -->
<pathelement location="${build.dir}"/>
</path>


<target name="prepare" description="创建build目录">
<delete dir="${build.dir}"/>
<mkdir dir="${build.dir}"/>
</target>

<!-- - - - - - - - - - - - - - - - - -
target: compile
- - - - - - - - - - - - - - - - - -->
<target name="compile" depends="prepare" description="编译">
<javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" includes="com/**">
<classpath refid="build.classpath"/>
</javac>
</target>

<!-- =================================
target: ejbjar
================================= -->
<target name="ejbjar" depends="compile" description="创建EJB发布包">
<jar jarfile="${basedir}\${ant.project.name}.jar">
<fileset dir="${build.dir}">
<include name="**/*.class"/>
</fileset>
</jar>
</target>

<!-- =================================
target: deploy
================================= -->
<target name="deploy" depends="ejbjar" description="发布EJB">
<copy file="${basedir}\${ant.project.name}.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy"/>
</target>

<!-- - - - - - - - - - - - - - - - - -
target: undeploy
- - - - - - - - - - - - - - - - - -->
<target name="undeploy" description="卸载EJB">
<delete file="${jboss.home}\server\${jboss.server.config}\deploy\${ant.project.name}.jar"/>
</target>
</project>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值