activemq实现了jms规范,使用jms发送消息,从消息的一端发送到另一端,当加入了activemq作为中间作,我们可以使用异步的方式发送消息.大概过程:发送者与activemq建立连接,先发送消息到activemq.然后,接收者与activemq建立连接,从activemq取回消息.发送者发消息的时候不依赖接收者,接收者接收消息的时候不依赖发送者,两个过程可以不同步进行.达到应用解耦的作用.如果接收者不去取消息,消息也没过期,那么消息会一直驻留在activemq这个中间件.
下面只是一个简单例子.接收者和发送者,几乎同时与activemq建立连接,接收者建立起监听,发送者一发送消息,接收者就马上接收到消息.
一.注册Connection Factory Bean.
三.创建Consumer.
1.注册MessageListener实现Bean.
其中ExamQueueListener.java如下:
2.使用connection,destination和listener创建consumer.
四.创建Producer.
1.使用spring的JmsTemplate.
五.单元测试(测试前不要忘了先启动activemq).ExamPublisherTest.java内容如下:
六.应用到Web
1.JmsController.java内容如下:
package com.exam.web;
import com.exam.jms.ExamPublisher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
@Controller
public class JmsController {
@Resource
private ExamPublisher examPublisher;
@RequestMapping("/test")
public String test(String message){
examPublisher.sendMessage(message);
return "redirect:/index.html";
}
}
2.index.html内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="test.do">
<input type="text" name="message" value="test"/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
3.启动jetty,在浏览器打开index.html页面测试(测试前不要忘了先启动activemq).
可能遇到的问题.当停止jetty或tomcat之后,activemq会报下面的警告.警告的原因估计是:客户端(包括Producer和Consumer)没有正确断开连接,上面的例子就是从PooledConnectionFactory生成多少个活跃的连接,就会有多少个警告,(PooledConnectionFactory的默认最大连接数是1,当然注册Bean时可以改).可能是直接断了进程,没有调用stop方法,从输出的警告,我认为问题不大.
下面只是一个简单例子.接收者和发送者,几乎同时与activemq建立连接,接收者建立起监听,发送者一发送消息,接收者就马上接收到消息.
一.注册Connection Factory Bean.
@Bean(destroyMethod = "stop")
public PooledConnectionFactory pooledConnectionFactory(){
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory("admin","admin","tcp://localhost:61616");
return new PooledConnectionFactory(activeMQConnectionFactory);
}
二.注册Destination Bean(使用队列发送消息).
@Bean
public ActiveMQQueue activeMQQueue(){
return new ActiveMQQueue("ExamQueueName");
}
三.创建Consumer.
1.注册MessageListener实现Bean.
@Bean
public ExamQueueListener examQueueListener(){
return new ExamQueueListener();
}
其中ExamQueueListener.java如下:
package com.exam.jms;
import javax.jms.Message;
import javax.jms.MessageListener;
/**
* Created by nil on 2014/8/26.
*/
public class ExamQueueListener implements MessageListener {
@Override
public void onMessage(Message message) {
System.out.println(message);
}
}
2.使用connection,destination和listener创建consumer.
@Bean
public DefaultMessageListenerContainer defaultMessageListenerContainer(){
DefaultMessageListenerContainer defaultMessageListenerContainer=new DefaultMessageListenerContainer();
defaultMessageListenerContainer.setConnectionFactory(pooledConnectionFactory());
defaultMessageListenerContainer.setDestination(activeMQQueue());
defaultMessageListenerContainer.setMessageListener(examQueueListener());
return defaultMessageListenerContainer;
}
四.创建Producer.
1.使用spring的JmsTemplate.
@Bean
public JmsTemplate jmsTemplate(){
return new JmsTemplate(pooledConnectionFactory());
}
2.将destination和jmsTemplate注入到examPublisher来注册Producer Bean.
@Bean
public ExamPublisher examPublisher(){
return new ExamPublisher(jmsTemplate(),activeMQQueue());
}
其中,ExamPublisher.java内容如下:
package com.exam.jms;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import java.util.Random;
/**
* Created by nil on 2014/8/26.
*/
public class ExamPublisher {
private JmsTemplate jmsTemplate;
private Destination destination;
public ExamPublisher(){}
public ExamPublisher(JmsTemplate jmsTemplate,Destination destination){
this.jmsTemplate = jmsTemplate;
this.destination = destination;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void setDestination(Destination destination) {
this.destination = destination;
}
public void sendMessage(final String msg){
jmsTemplate.send(destination,new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("test message " + msg);
}
});
}
}
五.单元测试(测试前不要忘了先启动activemq).ExamPublisherTest.java内容如下:
package com.exam.jms;
import com.exam.config.AppConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import javax.annotation.Resource;
/**
* Created by nil on 2014/8/26.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class,classes={AppConfig.class})
public class ExamPublisherTest {
@Resource
private ExamPublisher examPublisher;
@Test
public void testSendMessage(){
examPublisher.sendMessage("x123x");
}
}
六.应用到Web
1.JmsController.java内容如下:
package com.exam.web;
import com.exam.jms.ExamPublisher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
@Controller
public class JmsController {
@Resource
private ExamPublisher examPublisher;
@RequestMapping("/test")
public String test(String message){
examPublisher.sendMessage(message);
return "redirect:/index.html";
}
}
2.index.html内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="test.do">
<input type="text" name="message" value="test"/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
3.启动jetty,在浏览器打开index.html页面测试(测试前不要忘了先启动activemq).
可能遇到的问题.当停止jetty或tomcat之后,activemq会报下面的警告.警告的原因估计是:客户端(包括Producer和Consumer)没有正确断开连接,上面的例子就是从PooledConnectionFactory生成多少个活跃的连接,就会有多少个警告,(PooledConnectionFactory的默认最大连接数是1,当然注册Bean时可以改).可能是直接断了进程,没有调用stop方法,从输出的警告,我认为问题不大.
WARN | Transport Connection to: tcp://127.0.0.1:65279 failed: java.net.SocketException: Connection reset