首先是maven依赖:
<!-- activemq--> <dependency> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>4.3.18.RELEASE</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-core</artifactId> <version>5.5.0</version> </dependency> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-spring</artifactId> <version>4.5</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.9.0</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.7.0</version> </dependency>
接下来配置spring-context-activemq.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" 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:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd" > <!-- 实例化mq链接工厂(原始)--> <amq:connectionFactory brokerURL="tcp://localhost:61616" userName="admin" password="admin" id="amqConnectionFactory"></amq:connectionFactory> <!-- 实例化mq的链接池--> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="connectionFactory" ref="amqConnectionFactory"></property> <property name="maxConnections" value="10"></property> </bean> <!-- 实例化spring提供的链接,将mq提供的原始连接进行封装为spring提供的连接工厂 --> <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <property name="sessionCacheSize" value="3"></property> <property name="targetConnectionFactory" ref="amqConnectionFactory"></property> </bean> <!-- 实例化jmsTemplate对象 (不与某种产品关联 生产者) 与Spring 提供的工厂结合即可 --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 注入spring提供的连接工厂对象--> <property name="connectionFactory" ref="connectionFactory"></property> <!-- 默认点对点 --> <!-- <property name="pubSubDomain"></property>--> <!-- 指定默认队列名称 --> <property name="defaultDestinationName" value="notice-reward-message" ></property> </bean> <!-- 注册监听容器(消费者) acknowledge:消息确认机制 container-type:容器类型 default|simple simple:SimpleMessageListenerContainer 是一个用于异步消息的监听器容器,且支持事务 destination-type:目的地类型,使用队列作为目的地 connection-factory:连接工厂,spring-jms使用的连接工厂,必须是spring自主创建的 不能使用第三方工具创建的工厂如:ActiveMQConnectionFactory --> <jms:listener-container acknowledge="auto" destination-type="queue" container-type="default" connection-factory="connectionFactory"> <jms:listener destination="notice-reward-message" ref="rewardConsumerListener"/> </jms:listener-container> </beans>
(1)由于使用ActiveMQ官方原生的代码来发送MQ消息的代码比较复杂,因此采用JmsTemplate来发送MQ消息
(2)由于JmsTemplate发送MQ消息时每次都要创建Connection和Session。因此引入Spring提供的CachingConnectionFactory,起到类似于数据库连接池的效果
(3)注册JmsTemplate时,pubSubDomain这个属性的值要特别注意。默认值是false,也就是说默认只是支持queue模式,不支持topic模式。但是,如果将它改为true,则不支持queue模式。因此如果项目需要同时支持queue和topic模式,那么需要注册2个JmsTemplate,同时监听容器(<jms:listener-container>)也需要注册2个
接下来是生产者代码:
//@Scheduled(cron = "0 */1 * * * ?") //每分钟执行一次 //每天凌晨3点触发 @Scheduled(cron = "0 0 3 * * ?") @Transactional(readOnly = false) public void rewardMissionHandle() { this.sendMessage(new MoneystreamRecord()); } private void sendMessage(MoneystreamRecord moneystreamRecord) { // TODO Auto-generated method stub jmsTemplate.send(new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { System.out.println("将Record发送到:====》mq中"); // TODO Auto-generated method stub ObjectMessage message = session.createObjectMessage(moneystreamRecord); System.out.println(message.toString()); return message; } }); }
最后是消费者:
@Component public class RewardConsumerListener implements MessageListener{ @Autowired @Lazy(true) private UserService userService; @Override public void onMessage(Message message) { // TODO Auto-generated method stub try { ActiveMQObjectMessage m = (ActiveMQObjectMessage) message; MoneystreamRecord r = (MoneystreamRecord) m.getObject(); userService.push(r.getUser().getId(), "您的奖励金已发放,金额为:" + r.getChangeMoney() + "元。"); } catch (JMSException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }