EJB3.0 消息 异步

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ITSnack/article/details/83696416
Java消息服务(JMS Java Message Services)

提供了点对点模式(Point-to-Point Queue)和发布-订阅模式(Publish-Subscribe Topics).

Queue仅允许一个消息传送给一个客户(一对一):
消息的接收者和发送者之间不存在时间上的依赖关系。不论发送者发送消息时接收者是否在运行,接收者都可以提取信息。接收者对于成功处理的消息给出回执。

Topics可以有多个客户端(一对多,多对多):
向某个话题订阅的客户程序只能收到那些在它订阅之后发布的消息。为了接收到消息,订阅者必须保持活动状态。因此,发布者和订阅者之间存在时间上的依赖关系。

点对点消息模式通过一个消息队列(Queue)实现,消息的生产者向队列写入消息,消息的订阅者从队列提取消息。发布-订阅消息模式通过一个话题(Topic)节点构成的层次结构实现,消息的生产者向这个层次结构发布消息,消息的订阅者向这个结构订阅消息。

消息驱动的Bean只有一个Bean类。从某些方面看,消息驱动的Bean类似于无状态会话Bean:消息驱动的Bean不为特定的客户保留数据或对话状态。


java 代码

@MessageDriven(activationConfig={
@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",propertyValue="queue/Msg")
})

@MessageDriven注释指明这是一个消息驱动Bean,并使用@ActivationConfigProperty注释配置消息的各种属性,其中destinationType属性指定消息的类型,消息有两种类型topics 和queues,下面是这两种消息类型的介绍:
Topics 可以有多个客户端。用topic发布允许一对多,或多对多通讯通道。消息的产生者被叫做publisher, 消息接
受者叫做subscriber。destinationType属性对应值:javax.jms.Topic

Queue 仅仅允许一个消息传送给一个客户。一个发送者将消息放入消息队列,接受者从队列中抽取并得到消息,消息就会在队列中消失。第一个接受者抽取并得到消息后,其他人就不能再得到它。destinationType属性对应值:javax.jms.Queue
destination属性用作指定消息路径,消息驱动Bean在发布时,如果路径不存在,容器会自动创建该路径,当容器关闭时该路径会自动被删除

当一个消息到达queue/Msg队列时,就会触发onMessage方法,消息作为一个参数传入.


java 代码



package ejb;

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

@MessageDriven(activationConfig={
@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",propertyValue="queue/Msg")
})
public class Msg implements MessageListener {

public void onMessage(Message msg) {
// TODO Auto-generated method stub
TextMessage tmsg = (TextMessage) msg;
try{
System.out.println(tmsg.getText());
}catch(JMSException e){
e.printStackTrace();
}
}

}


java 代码

package test;

import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.JMSException;
import javax.jms.QueueSession;
import javax.jms.Queue;
import javax.jms.TextMessage;
import javax.jms.QueueSender;
import javax.naming.*;

public class MsgTest {
public static void main(String[] args){
QueueConnection conn;
QueueSession ssn;
Queue queue;
QueueSender sender;
TextMessage msg;
try{
InitialContext ctx = new InitialContext();
QueueConnectionFactory qcf =(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
conn = qcf.createQueueConnection();
ssn = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
queue =(Queue) ctx.lookup("queue/Msg");
msg = ssn.createTextMessage("HELLO WORLD!");
sender = ssn.createSender(queue);
sender.send(msg);
sender.close();
}catch(NamingException e){
e.printStackTrace();
}catch(JMSException e1){
e1.printStackTrace();
}
}
}


(1) 得到一个JNDI初始化上下文(Context);
例子对应代码:


java 代码

Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ctx = new InitialContext(props);


(2) 根据上下文来查找一个连接工厂TopicConnectFactory/ QueueConnectionFactory (有两种连接工厂,根据是topic/queue来使用相应的类型);
例子对应代码:


java 代码

QueueConnectionFactory qcf =(QueueConnectionFactory) ctx.lookup("ConnectionFactory");


(3) 从连接工厂得到一个连接(Connect 有两种[TopicConnection/ QueueConnection]);
例子对应代码:conn = qcf.createQueueConnection();

(4) 通过连接来建立一个会话(Session);
例子对应代码:ssn = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
这句代码意思是:建立不需要事务的并且能自动接收消息收条的会话,在非事务Session 中,消息传递的方式有三种:
Session.AUTO_ACKNOWLEDGE :当客户机调用的receive方法成功返回,或当MessageListenser 成功处理了消息,session将会自动接收消息的收条。

Session.CLIENT_ACKNOWLEDGE :客户机通过调用消息的acknowledge方法来接收消息。接收发生在session层。接收到一个被消费的消息时,将自动接收该session已经 消费的所有消息。例如:如果消息的消费者消费了10条消息,然后接收15 个被传递的消息,则前面的10 个消息的收据都会在这15 个消息中被接收。

Session.DUPS_ACKNOWLEDGE :指示session缓慢接收消息。

(5) 查找目的地(Topic/ Queue);
例子对应代码:queue =(Queue) ctx.lookup("queue/Msg");

(6) 根据会话以及目的地来建立消息制造者(TopicPublisher/QueueSender)和消费者(TopicSubscriber/QueueReceiver).
例子对应代码:


java 代码

msg = ssn.createTextMessage("HELLO WORLD!");
sender = ssn.createSender(queue);
sender.send(msg);



----------------------------------------------------------
发送对象。。。。。。
==============================================================

jboss-5.1.0.GA\server\default\deploy\messaging\destinations-service.xml

<mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=The_Queue_Name" xmbean-dd="xmdesc/Queue-xmbean.xml">
<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
<depends>jboss.messaging:service=PostOffice</depends>
</mbean>

-------------------------------------
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.interceptor.Interceptors;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;

/**
* 异步连接工厂
*/
@Resource(mappedName = "ConnectionFactory")
private QueueConnectionFactory qcf;

/**
* 异步队列
*/
@Resource(mappedName = "queue/The_Queue_Name")
private Queue queue;


private void sendMain(List trList) {
QueueConnection conn = null;
QueueSession session = null;
MessageProducer messageProducer = null;
ObjectMessage objectMessage = null;

try {
conn = qcf.createQueueConnection();
session = conn.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
messageProducer = session.createProducer(queue);
objectMessage = session.createObjectMessage((Serializable) trList);

// 发送数据到服务器
messageProducer.send(objectMessage);
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
messageProducer.close();
session.close();
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
展开阅读全文

没有更多推荐了,返回首页