监听器两种实现方案:
1. 采用原生的JMS的MessageListener
2. 采用Spring的SessionAwareMessageListener
1.1 定义接口PersonService :
public interface PersonService { public void sendMessage( String message ); }
1.2 JMS方案,定义ConsumerMessageListener1,实现的是JMS的接口 MessageListener:
/** * 监听器有两种实现方案: * 一种是采用原生的jms的MessageListener * 另一种是采用spring的方案 SessionAwareMessageListener * */ public class ConsumerMessageListener1 implements MessageListener { @Override public void onMessage(Message message) { if( message instanceof TextMessage ){ TextMessage tm = (TextMessage) message; try { System.out.println( "接收到的是个文本消息: " + tm.getText() +"\n" ); } catch (JMSException e) { e.printStackTrace(); } } } }
1.3 定义类PersonServiceImpl 实现接口PersonService:
@Service("personServiceImpl") public class PersonServiceImpl implements PersonService { private Destination destination; private JmsTemplate jmsTemplate; @Override public void sendMessage(final String message) { System.out.println( "生产者发送消息: " + message ); jmsTemplate.send(destination,new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { Message msg = session.createTextMessage(message); msg.setJMSDeliveryMode( DeliveryMode.NON_PERSISTENT ); return msg; } }); } @Resource(name="queueDestination") public void setDestination(Destination destination) { this.destination = destination; } @Resource(name="jmsTemplate") public void setJmsTemplate(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } }
1.4 测试类(针对原生方案)Test1:
public class Test1 { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); PersonService ps = (PersonService) ac.getBean("personServiceImpl"); for( int i=0;i<5;i++){ ps.sendMessage("Hello World " + i ); } } }
1.5 Test1的测试结果:
// Test测试: 生产者发送消息: Hello World 0 接收到的是个文本消息: Hello World 0 生产者发送消息: Hello World 1 接收到的是个文本消息: Hello World 1 生产者发送消息: Hello World 2 接收到的是个文本消息: Hello World 2 生产者发送消息: Hello World 3 接收到的是个文本消息: Hello World 3 生产者发送消息: Hello World 4 接收到的是个文本消息: Hello World 4
2.1 定义ConsumerMessageListener2 ,并且实现由Spring提供的SessionAwareMessageListener ,它可以在回调方法中传入session 以此回送消息到生产者。
/** * SessionAwareMessageListener : * 由Spring提供 它可以在回调方法中传入session 以此回送消息到生产者。 * */ @Component("consumerMessageListener2") public class ConsumerMessageListener2 implements SessionAwareMessageListener<TextMessage> { private Destination destination; @Override public void onMessage(TextMessage message, Session session) throws JMSException { System.out.println( "接收到消息是个文本消息: " + message.getText() ); //通过session创建producer对象 再回送消息。 //从message中取出消息回送的目的地 以便创建生产者。 MessageProducer producer = session.createProducer( message.getJMSReplyTo() ); //创建一条消息: Message msg = session.createTextMessage( "生产者发过来的消息已经处理完毕..." ); //发送 producer.send(msg); } @Resource( name="sendQueueDestination") public void setDestination(Destination destination) { this.destination = destination; } }
2.2 定义PersonServiceImpl2:
@Service("personServiceImpl2") public class PersonServiceImpl2 implements PersonService { private Destination destination; //用于存发送消息的队列 private JmsTemplate jmsTemplate; //jms操作模板 private Destination replyDestination; //用于存回复消息的队列 @Override public void sendMessage(final String message) { System.out.println( "生产者2发送消息: " + message ); jmsTemplate.send(destination,new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { Message msg = session.createTextMessage(message); //设置回复消息的目的地队列: msg.setJMSReplyTo(replyDestination); //设置发送的消息类型为非持久化消息: msg.setJMSDeliveryMode( DeliveryMode.NON_PERSISTENT ); //创建一个消费者 用于接收对方回复的消息 注意这个消费者监听 replyDestination MessageConsumer consumer = session.createConsumer(replyDestination); consumer.setMessageListener( new MessageListener() { @Override public void onMessage(Message m) { try { System.out.println( "接收道的回复消息为: " + ((TextMessage)m).getText() ); } catch (JMSException e) { e.printStackTrace(); } } }); return msg; } }); } @Resource(name="sendQueueDestination") public void setDestination(Destination destination) { this.destination = destination; } @Resource(name="jmsTemplate") public void setJmsTemplate(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } @Resource(name="replyQueueDestination") public void setReplyDestination(Destination replyDestination) { this.replyDestination = replyDestination; } }
2.3 Test2测试类:
public class Test2 { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); PersonService ps = (PersonService) ac.getBean("personServiceImpl2"); ps.sendMessage("我是生产者2生产的消息 , personServiceImpl2 " ); } }
2.4 Test2测试结果:
//Test2结果: 生产者2发送消息: 我是生产者2生产的消息 , personServiceImpl2 接收道的回复消息为: 生产者发过来的消息已经处理完毕...
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 启用注解解析器 --> <context:annotation-config /> <!-- 因为采用了混合解析方式( 有一部分配置在xml中,有一部分在java类中,所以要让spring的注解解析器去扫描包 --> <context:component-scan base-package="com.xj.jms4" /> <!-- 启用aspectj的注解方式的代理 --> <aop:aspectj-autoproxy /> <!-- 创建一个真正的基于 jms提供者的联接工厂 --> <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <!-- ActiveMQ联接池的方案 --> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="connectionFactory" ref="targetConnectionFactory" /> <property name="maxConnections" value="100" /> </bean> <!-- 创建spring联接工厂 --> <bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory" ref="pooledConnectionFactory" /> </bean> <!-- <bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory" <property name="targetConnectionFactory" ref="pooledConnectionFactory" /> </bean> --> <!-- 配置jmsTemplate --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="singleConnectionFactory" /> </bean> <!-- 配置目的地: 这有两种:一种是 Queue对应是 P2P模式,另一种是 Topic 对应的是 发布/订阅模式, --> <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>myqueue</value> </constructor-arg> </bean> <!-- <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic"> <constructor-arg> <value>mytopic</value> </constructor-arg> </bean> --> <!-- 配置临听器 --> <bean id="consumerMessageListener1" class="com.xj.jms4.ConsumerMessageListener1"> </bean> <!-- 配置临听器运行时所在的容器 --> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="singleConnectionFactory" /> <property name="destination" ref="queueDestination" /> <property name="messageListener" ref="consumerMessageListener1" /> </bean> <!-- 以下用于存放生产者发送的信息 --> <bean id="sendQueueDestination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>sendQueue</value> </constructor-arg> </bean> <!-- 以下用于存放消费者回复的信息 --> <bean id="replyQueueDestination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>replyQueue</value> </constructor-arg> </bean> <!-- 配置 sessionAware的临听器 --> <bean id="consumerMessageListener2" class="com.xj.jms4.ConsumerMessageListener2" > <property name="destination" ref="sendQueueDestination" /> <!-- <property name="replyDestination" ref="replyQueueDestination" /> --> </bean> <!-- 配置 consumerMessageListener2的容器 --> <bean id="sessionAwareListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" > <property name="connectionFactory" ref="singleConnectionFactory" /> <property name="destination" ref="sendQueueDestination" /> <property name="messageListener" ref="consumerMessageListener2" /> </bean> </beans>
最后是导入的包(....):