本文主要是示范基于Maven的ActiveMQ+Spring的简单使用,基于ActiveMQ消息代理的Spring JMS消息配置,以及定时任务的使用。
JMS简介
JMS提供了应用之间的异步通信机制,当异步发送消息时,客户端不需要等待服务端处理消息结果。
构建JMS
两个主要概念:消息代理(message broker)和目的地(destination)。
当一个应用发送消息时,会把消息交给一个消息代理。消息代理实际上是JMS版的邮局。消息代理可以确保消息被投递到指定的目的地,同时释放发送者,使其能够继续其他的业务。
目的地就像一个邮箱,可以将消息放入邮箱,直至有人将其取走。JMS中有两种类型的目的地:队列和主题。,分别应用于队列的点对点模型和主题的发布/订阅模型。
点对点消息模型
每一个消息都有一个发送者和一个接收者。
当消息代理得到消息后,会将消息放入到消息队列中,接收者请求队列中的下一条消息时,该消息就会从队列中取出,投递给接收者。因为消息投递后会从队列中删除,因此可以保证消息只投递给一个接收者。
可以使用多个接收者来处理队列中的消息,不过每个接收者都会处理自己接收到的消息,需要多个接收者监听队列。
发布-订阅消息模型
消息会发送给一个主题,多个接收者可以监听一个主题。与队列不同的是,消息不再是只投递给一个接收者,所有主题的订阅者都可以接收到此消息。
JMS的优点
- 无需等待
- 面向消息和解耦
- 位置独立
- 确保投递
在Spring中搭建消息代理
安装ActiveMQ
ActiveMQ是一个开源的消息代理, 也是使用JMS进行异步消息传递的最佳选择。在官方网站下载后,解压缩安装包,点击apache-activemq-5.12.1\bin\activemq.bat
运行即可(64位操作系统可能需要点击apache-activemq-5.12.1\bin\win64\activemq.bat
运行)。运行后进入http://localhost:8161/
表明安装成功, 这时就可以使用它进行消息代理了。
maven配置
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
Spring配置
使用JMS连接工厂通过消息代理发送消息,因为选择了ActiveMQ作为消息代理,因此需要配置JMS连接工厂,让它知道如何连接到ActiveMQ。ActiveMQConnectionFactory
是ActiveMQ自带的连接工厂,可以在Spring中进行配置。
使用JmsTemplate
可以创建连接、获得会话以及发送和接收消息。
1 | "1.0" encoding="UTF-8" xml version= |
发送消息
当调用JmsTemplate
的send()
方法,JmsTemplate
将负责JMS连接、会话并代表发送者发送消息。这里使用了默认的消息目的地。
1 | package activemq.publisher; |
接收消息监听器
1 | package activemq.consumer; |
测试
使用Spring的定时任务定时发送消息。
定时任务配置:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34"1.0" encoding="UTF-8" xml version=
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<bean id="QuartzFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="capacityDataPublisherJobTrigger" />
</list>
</property>
</bean>
<bean id="capacityDataPublisherJob" class="activemq.TestSenderService"
init-method="run">
</bean>
<bean id="capacityDataPublisherJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="capacityDataPublisherJobDetail" />
<property name="cronExpression">
<value>0 0/5 * * * ?</value>
</property>
</bean>
<bean id="capacityDataPublisherJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="capacityDataPublisherJob" />
<property name="targetMethod" value="run" />
<property name="concurrent" value="false" />
</bean>
</beans>
定时任务
1 | package activemq; |
测试结果
在tomcat中运行项目。
运行后发送了两条消息,消息队列中显示:
重启项目时,接收消息监听器会处理队列中所有的消息,项目运行时,每次发送消息成功后都会触发接收消息监听器:
入列和出列:
代码获取地址:
https://github.com/hoxis/JavaWeb/tree/master/activemq