消息驱动bean 分2种
一种是queue/一种是topic
先简单写下2种方式的代码,然后再解释下2种方式的区别:
1.queue:
首先要绑定一个目标服务。(就是写一个xml文件,然后部署到jboss中,jboss会自动绑定该服务)
文件名字需要以-service.xml结尾,比如我想创建一个名叫yghQueue的消息队列服务,
那么可以叫yghQueue-service.xml。
(1):yghQueue-service.xml内容:
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mqdestination:service=Queue,name=yghQueue">
<attribute name="JNDIName">queue/yghQueue</attribute>
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>
写好xml后,复制到jboss中后,在jboss控制台中
自动绑定该服务,显示JNDI名称。代码中可以通过该名称找到该服务。
(2)jndi.properties内容:
java.naming.provider.url=localhost\:1099
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
Jndi.properties主要是定义2个变量声明jndi的端口及上下文工程。
当然你也可以在代码中写,不过直接写在配置文件中比较简单。Jndi.properties的默认路径在src下。
(3)消息发送代码:
public static void main(String[] args) {
try {
InitialContext ic=new InitialContext();//创建一个InitialContext对象,可以通过lookup方法,传入对象的jndi名称得到对象。
QueueConnectionFactory qf=(QueueConnectionFactory )ic.lookup("QueueConnectionFactory");//得到jboss的QueueConnectionFactory对象
Connection conn=qf.createConnection();
Session session=conn.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);//创建会话
Destination des=(Destination)ic.lookup("queue/yghQueue");//得到目标消息队列对象
MessageProducer mp=session.createProducer(des);//创建消息制造器,传入目标消息队列对象。
mp.send(session.createTextMessage("ni cai"));//消息制造器向目标队列发送文本消息。
} catch (Exception e) {
e.printStackTrace();
}
}
代码写好后,yghQueue-service.xml也部署好后,直接运行代码,运行后什么都没发送,但是实际上,“ni hao”这个文本消息已经发送给了queue/yghQueue消息队列中。
(4)在(3)完成后,说明queue/yghQueue消息队列中已经有了”ni hao”这个消息了,那么怎么取出这个消息呢?
与其说取出消息,不如说,时刻在监听这个消息队列,当消息到达时,可以直接打印出来,由于是queue方式,所以即使是一开始没在监听,但是后来监听了,那么监听之前用户发送的显示还是会得到。
接收消息代码:
@MessageDriven(activationConfig=
{
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="queue/yghQueue"),
@ActivationConfigProperty(propertyName="acknowledgeMode",
propertyValue="Auto-acknowledge")
})//这里一串注释的意思是,说明你这个类在监听哪个消息队列
public class MessageDriverTest implements MessageListener{
@Override
public void onMessage(Message msg) {//在这里写用户发送信息后需要处理的逻辑,这里直接输出,那么将代码部署在jboss控制台后会看到相应的输出
TextMessage tm=(TextMessage)msg;
try {
System.out.println(tm.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
部署在jboss后:
在控制台中输出”ni hao”。
需要强调的是,queue方式支持离线模式,就是你这个监听代码没有部署在jboss中,但是用户消息已经发送到队列消息中后,你再部署这个监听程序还是可以接受到用户刚才发送的消息。
2 topic:
Topic 跟queue的代码中的区别就是
把代码中的queue改为topic就可以了,这里直接贴出代码,就不详细解释了。
Xml:
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mqdestination:service=Topic,name=yghTopic">
<attribute name="JNDIName">topic/yghTopic</attribute>
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>
Jndi.properties不变
消息发送代码:
public static void main(String[] args) {
try {
InitialContext ct=new InitialContext();
QueueConnectionFactory connectFactory=(QueueConnectionFactory)ct.lookup("QueueConnectionFactory");
Connection connection=connectFactory.createConnection();
Destination destination=(Destination)ct.lookup("topic/yghTopic");
Session session=connection.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
MessageProducer mp=session.createProducer(destination);
mp.send(session.createTextMessage("ni hao"));
} catch (Exception e) {
e.printStackTrace();
}
}
接收消息代码:
@MessageDriven(activationConfig=
{
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="topic/yghTopic"),
@ActivationConfigProperty(propertyName="acknowledgeMode",
propertyValue="Auto-acknowledge")
})
public class MessageDriverTest2 implements MessageListener{
@Override
public void onMessage(Message msg) {
TextMessage tm=(TextMessage)msg;
try {
System.out.println(tm.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
代码基本不变,就是queue改为topic。
区别:queue只是单对单的,
Topic相单于单对多。
Queue发送消息给消息队列后,谁先监听这个消息队列,谁就得到消息,支持离线模式。
Topic:发送消息给消息队列后,所有监听该消息队列的都得到该消息,不支持离线模式。