首先我们从JmsGatewaySupport的使用上开始说起
我们先创建一个maven工程,工程结构如下
我的pom.xml文件如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pcx</groupId>
<artifactId>amqproducer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>amqproducer</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.4.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.11.1</version>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
<!-- Test Dependency Begin -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
接着我们创建一个类去继承JmsGatewaySupport,JmsGatewaySupport是一个jms消息收发的扩展类,我们在类里面注入一个jmsTemplate就可以了
/**
*
*/
package com.pcx.amqproducer;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.support.JmsGatewaySupport;
/**
*
* @author scarletbullet
* @version $Id: MySpringProducer2.java
*/
public class MySpringProducer2 extends JmsGatewaySupport {
public void send(final String destination){
<span style="white-space:pre"> </span>//<span style="font-family: Arial, Helvetica, sans-serif;">setPubSubDomain(false)的作用是告诉我们的jmsTemplate我们要发送的是一/<span style="white-space:pre"> </span>//个队列,如果是true那么发送的就是topic</span>
this.getJmsTemplate().setPubSubDomain(false);
//<span style="font-family: Arial, Helvetica, sans-serif;">send(destination, new MessageCreator() )这个send方法的第一个参数是一个String请不要搞错,我们配置的是destinationName</span>
this.getJmsTemplate().send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
MapMessage message=session.createMapMessage();
message.setString("userId", "4545454");
message.setString("userName", "jmstemplateGatewag");
message.setInt("age",25);
return message;
}
});
System.out.println("成功发送了一条JMS消息");
}
}
接下来在spring-context.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- ActiveMQ服务地址 -->
<property name="brokerURL" value="tcp://192.168.1.10:61616" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<bean id="mySpringProducer" class="com.pcx.amqproducer.MySpringProducer2">
<property name="jmsTemplate" ref="jmsTemplate"/>
</bean>
</beans>
我们编写测试类
package com.pcx.amqproducer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
ApplicationContext context;
context= new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml");
MySpringProducer2 mySpringProducer = (MySpringProducer2) context.getBean("mySpringProducer");
mySpringProducer.send("que12");
}
}
我们像队列“que12”发送了一条消息,我们运行一下看看
我们可以看到发送成功了
知道了怎么发消息,接下来我们创建一个新的发送类,让它变得通用
/**
*
*/
package com.pcx.amqproducer;
import java.io.Serializable;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.support.JmsGatewaySupport;
import org.springframework.util.StringUtils;
/**
*
* @author scarletbullet
* @version $Id: MySpringProducer3.java
*/
public class MySpringProducer3 extends JmsGatewaySupport{
public void send(final String destination, final Serializable msg) {
if (StringUtils.isEmpty(destination) || msg == null) {
throw new RuntimeException("消息参数异常");
}
//如果我们的目的地名称为topic开头那么我们设置成true,不是那么认为它是queue
if (destination.startsWith("topic")) {
this.getJmsTemplate().setPubSubDomain(true);
} else {
this.getJmsTemplate().setPubSubDomain(false);
}
this.getJmsTemplate().send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
Message message = session.createObjectMessage(msg);
return message;
}
});
}
}
在spring-context.xml中增加如下配置
<bean id="mySpringProducer3" class="com.pcx.amqproducer.MySpringProducer3">
<property name="jmsTemplate" ref="jmsTemplate"/>
</bean>
修改我们的测试类
package com.pcx.amqproducer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
ApplicationContext context;
context= new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml");
MySpringProducer3 mySpringProducer = (MySpringProducer3) context.getBean("mySpringProducer3");
mySpringProducer.send("topic_one",new String("测试"));
}
}
然后运行一下测试类
我们可以从amq的控制台看到
这样我们就可以通过名称来用一个类发送topic和queue两种模型的消息了
接下来我们创建一个maven工程来编写消息消费端,工程结构如下
pom文件如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pcx</groupId>
<artifactId>amqwebconsumer</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>amqwebconsumer Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Jar版本管理 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springframework>3.2.4.RELEASE</springframework>
<log4j>1.2.17</log4j>
<activemq>5.11.1</activemq>
</properties>
<dependencies>
<!-- Spring web mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework}</version>
</dependency>
<!-- 提供JMS,Freemarker,Quartz集成服务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework}</version>
</dependency>
<!-- 集成JMS -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${springframework}</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j}</version>
</dependency>
<!-- Active MQ -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>${activemq}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>amqwebconsumer</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.14.v20131031</version>
<configuration>
<webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopPort>9999</stopPort>
<webAppConfig>
<contextPath>/w</contextPath>
</webAppConfig>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
</build>
</project>
这里使用的是springmvc框架,这个搭建比较简单就不说了
我们创建一个类实现消息监听器,这样我们可以异步收消息了
/**
*
*/
package com.pcx.amqweb;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
/**
*
* @author scarletbullet
* @version $Id: MyListener.java, v 0.1 2016-5-16 上午1:04:17 scarletbullet Exp $
*/
public class MyListener implements MessageListener {
/**
* @see javax.jms.MessageListener#onMessage(javax.jms.Message)
*/
public void onMessage(Message message) {
MapMessage mapMessage=(MapMessage)message;
try {
System.out.println("aaaaaaaaaaaaaaaa");
System.out.println(mapMessage.getString("userName"));
} catch (Exception e) {
}
}
}
spring配置文件代码如下
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.1.10:61616" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<bean id="myListener" class="com.pcx.amqweb.MyListener" />
<bean id="generalListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer" abstract="true">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<bean id="listenerone" parent="generalListener">
<property name="destinationName" value="que12"/>
<property name="messageListener" ref="myListener" />
</bean>
</beans>
我们以后只要继承一个generallistener就可以监听queue或者topic的消息了
这样配置简化很多
mylistener里面可以写我们的业务逻辑
我们向"que12"发送一条消息,结果可以收到
这样我们的消息收发通用代码就完成了,当然我这里没有做过多的封装,有兴趣的朋友可以自己封装一下