spring整合activemq 发送实体类对象

首先是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();
        }
    }

}

 

posted @ 2021-01-08 14:55  陈扬天  阅读(421)  评论(0编辑  收藏  举报