一、队列的生产和消费者
pom.xml添加Spring相关的坐标,完整内容如下所示。还是保持linux系统的mq服务开始
<?xml version="1.0" encoding="UTF-8"?>
<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>org.wsy</groupId>
<artifactId>ActiveMQ</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!--ActiveMQ-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.9</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>3.16</version>
</dependency>
<!--FastJson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<!--ActiveMQ对JMS的支持,整合Spring和ActiveMQ-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.23.RELEASE</version>
</dependency>
<!--ActiveMQ所需要的pool包-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.9</version>
</dependency>
<!--Spring AOP相关的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.23.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.23.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.23.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.23.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<!--Junit/Log4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
Spring项目需要一个applicationContext.xml配置文件,在resources目录下创建applicationContext.xml配置文件,内容如下。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启包自动扫描-->
<context:component-scan base-package="com.wsy.spring.activemq"/>
<!--配置生产者-->
<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory">
<!--真正可以产生Connection的ConnectionFactory,由对应的JMS服务厂商提供-->
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.0.123:61616"/>
</bean>
</property>
<property name="maxConnections" value="100"/>
</bean>
<!--队列的目的地,点对点传输模式-->
<bean id="destnationQueue" class="org.apache.activemq.command.ActiveMQQueue">
<!--队列的名称是spring-active-quque-->
<constructor-arg index="0" value="spring-active-quque"/>
</bean>
<!--Spring提供的JMS工具表,它可以进行消息发送、接收等-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory"/>
<property name="defaultDestination" ref="destnationQueue"/>
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
</property>
</bean>
</beans>
生产者 创建SpringMQ_Producer类,代码如下。
package com.wsy.spring.activemq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
@Service
public class SpringMQ_Producer {
@Autowired
private JmsTemplate jmsTemplate;
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过Spring容器获取SpringMQ_Producer对象的实例,在getBean时候,默认是类名首字母小写
SpringMQ_Producer springMQ_producer = (SpringMQ_Producer) applicationContext.getBean("springMQ_Producer");
springMQ_producer.jmsTemplate.send(new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("Spring和ActiveMQ整合");
}
});
// Lambda表达式写法
// springMQ_producer.jmsTemplate.send(session -> session.createTextMessage("Spring和ActiveMQ整合"));
System.out.println("消息发送完毕!");
}
}
运行main方法,可以在ActiveMQ的管理界面看到一个名为spring-active-quque的队列,里面有一条消息,此时消息生产者和Spring的整合完成了。
创建SpringMQ_Consumer类,代码如下。
package com.wsy.spring.activemq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
@Service
public class SpringMQ_Consumer {
@Autowired
private JmsTemplate jmsTemplate;
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过Spring容器获取SpringMQ_Producer对象的实例,在getBean时候,默认是类名首字母小写
SpringMQ_Consumer springMQ_consumer = (SpringMQ_Consumer) applicationContext.getBean("springMQ_Consumer");
String message = (String) springMQ_consumer.jmsTemplate.receiveAndConvert();
System.out.println(message);
}
}
二、主题(Topic)的生产和消费
要用到主题,需要先修改applicationContext.xml文件,添加一个主题的bean,将jmsTemplate的defaultDestination属性值换做topic的id即可
<!-- 队列的目的地 点对点传输模式-->
<bean id="destnationQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="spring-active-queue"/>
</bean>
<!--**** 增加的 主题的目的地,发布订阅传输模式 **** -->
<bean id="destnationTopic" class="org.apache.activemq.command.ActiveMQTopic">
<!--主题的名称是spring-active-topic-->
<constructor-arg index="0" value="spring-active-topic"/>
</bean>
<!--Spring提供的JMS工具表,它可以进行消息发送、接收等-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory"/>
<!-- **** 将原来的队列目的地换成主题start ****-->
<property name="defaultDestination" ref="destnationTopic"/>
<!-- **** 将原来的队列目的地换成主题end ****-->
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
</property>
</bean>
其余代码不用动,topic和queue不同的地方在于:如果用的是topic,那么要先启动消费者监听,再启动生产者产生消息。这就是Spring的强大之处,只需要修改xml配置文件,就可以实现代码的复用。只不过先启动消费者,再启动生产者
三、Spring整合ActiveMQ之监听器配置
在applicationContext.xml配置文件中添加如下代码,添加MyMessageListener类,代码如下
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory"/>
<!--*** 这里也要对应目的地是topic start*** -->
<property name="defaultDestination" ref="destnationTopic"/>
<!--*** 这里也要对应目的地是topic end*** -->
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter"></bean>
</property>
</bean>
<!--配置监听程序-->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsFactory"/>
<!--*** 这里也要对应目的地是topic start*** -->
<property name="destination" ref="destnationTopic"/>
<!--*** 这里也要对应目的地是topic end*** -->
<property name="messageListener" ref="myMessageListener"/>
</bean>
第一种方式:通过配置文件的方式引入了MyMessageListener.java,代码如下。
<!--可以通过xml方式引入MyMessageListener,也可以通过注解的方式引入,采用其一即可-->
<bean id="myMessageListener" class="com.wsy.spring.activemq.MyMessageListener"/>
第二种方式:在MyMessageListener类上面加上@Component注解即可。
package com.wsy.spring.activemq;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@Component
public class MyMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
完成了上面的工作之后,我们只需要启动生产者,不需要启动消费者,因为Spring的配置文件中已经写了监听器,Spring会帮我们完成监听的功能,从而调用MyMessageListener中的onMessage方法。
我们测试一下效果,只启动生产者,可以在控制台看到onMessage()方法已经执行了。
如果说,没有看到输出,那么请检查下applicationContext.xml文件的配置。看一下jmsContainer的destination属性是topic还是queue?看一下jmsTemplate的defaultDestination是topic还是queue,这两个保持一致才可以。
另外,在控制台输出信息的时候,有可能先输出消息,后输出“消息发送完毕”类似字样,多运行几次试试就可以了,这个问题不大。
原文链接
https://blog.youkuaiyun.com/qq_36059561/article/details/103830447
https://blog.youkuaiyun.com/qq_36059561/article/details/103831082
https://blog.youkuaiyun.com/qq_36059561/article/details/103831409
https://blog.youkuaiyun.com/qq_36059561/article/details/103831810
1085

被折叠的 条评论
为什么被折叠?



