Spring Framework JMS 用 activeMQ的实现

1.maven 中导入 activeMQ的依赖

  1. 导入 activeMQ-all 的依赖
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-all</artifactId>
        <version>5.15.0</version>
    </dependency>
                
    
    注:导入activemq 所有的 依赖jar包 ,可能会导致项目中jar 冲突,可能有的同学会说 可以排除冲突的jar。经过本人尝试 发现 排除不了 activemq-all 中的冲突的 jar ,原因是 activemq-all pom中的使用了 “maven-shade-plugin” 插件(直接将所有的依赖 打成了一个 jar 包) 导致 exclusion 无效。

2.根据项目而定 导入activeMQ相关的jar包

<!--jms activeMQ-->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-client</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-openwire-legacy</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-camel</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>commons-pool2</artifactId>
                    <groupId>org.apache.commons</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>activemq-spring</artifactId>
                    <groupId>org.apache.activemq</groupId>
                </exclusion>
            </exclusions>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-jaas</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-broker</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>jackson-annotations</artifactId>
                    <groupId>com.fasterxml.jackson.core</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>jackson-databind</artifactId>
                    <groupId>com.fasterxml.jackson.core</groupId>
                </exclusion>
            </exclusions>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-console</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-spring</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-pool</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-jms-pool</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-amqp</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-http</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-mqtt</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-stomp</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-kahadb-store</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-jdbc-store</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-leveldb-store</artifactId>
            <version>5.15.0</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>leveldbjni</artifactId>
                    <groupId>org.fusesource.leveldbjni</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq.protobuf</groupId>
            <artifactId>activemq-protobuf</artifactId>
            <version>1.1</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.fusesource.hawtbuf</groupId>
            <artifactId>hawtbuf</artifactId>
            <version>1.11</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.jasypt</groupId>
            <artifactId>jasypt</artifactId>
            <version>1.9.2</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-jms_1.1_spec</artifactId>
            <version>1.1.1</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-j2ee-management_1.1_spec</artifactId>
            <version>1.0.1</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-annotation_1.0_spec</artifactId>
            <version>1.1.1</version>
            <classifier>sources</classifier>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <!--jms activeMQ end-->

注:我在 active-all上去掉了 一些日志的jar包 ,和不需要用的 jar包

2 配置 spring-jms xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       
       xmlns:jms="http://www.springframework.org/schema/jms"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
 
        http://www.springframework.org/schema/jms
        http://www.springframework.org/schema/jms/spring-jms.xsd">

        <!--jms 注解驱动-->
        <jms:annotation-driven ></jms:annotation-driven>

        <!--activeMQ的连接工厂-->
        <bean id="activeMQConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
            <property name="userName" value="admin"></property>
            <property name="password" value="admin"></property>
            <property name="brokerURL" value="tcp://192.168.0.131:61616"></property>
        </bean>

        <!--destination-resolver 目标资源 -->
        <bean id="dynamicDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver">
        </bean>
        <bean id="jmsReceiveListener" class="com.hua.fileplat.cloud.base.jms.JmsReceiveListener"></bean>

        <!--消息队列-->
        <jms:listener-container
                factory-id="jmsFactory"
                connection-factory="activeMQConnectionFactory"
                destination-resolver="dynamicDestinationResolver"
                destination-type="queue"
                response-destination-type="queue"
                receive-timeout="3000"
        >
            <jms:listener destination="dynamicDestinationResolver" ref="jmsReceiveListener"></jms:listener>
        </jms:listener-container>
        <bean id="jmsTemplate" name="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory" ref="activeMQConnectionFactory"></property>
            <!--如果没有使用JTA,对于上面的配置如果把属性 sessionTransacted 设成true jms事务与 数据库事务融合-->
            <property name="sessionTransacted" value="true"></property>
        </bean>
</beans>

注 : 我这里简单的实现了 消息队列 接收消息侦听和 JMS事务

  1. 侦听器容器中的 client-id 属性 是用于 订阅模式下的 属性
  2. sessionTransacted=true 是让 JMS事务 融合到 spring 事务中,这样 就可以和数据库 事务一起配合是用。

2 侦听器实例

发送消息

package com.hua.fileplat.cloud.user.service;

import com.hua.fileplat.cloud.user.dao.RoleDao;
import com.hua.fileplat.cloud.user.dto.RoleDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import java.util.Date;
import java.util.List;

/**
 * 角色服务
 */
@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleDao roleDao;

    @Override
    public List<RoleDto> selectRole() {
        return roleDao.selectRole();
    }

    @Autowired
    public JmsTemplate jmsTemplate;

    /**
     * 嵌套回滚  https://www.cnblogs.com/duanxz/p/4746892.html
     * @return
     */
    @Override
    @Transactional
    public boolean transactionTest1() {
        List<RoleDto> roleDtoList=selectRole();
        RoleDto roleDto= roleDtoList.get(0);
        /*try{
            transactionTest2(roleDto);
        }catch (Exception e){
        }finally {
            System.out.println(roleDto.getId());
        }*/
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("hahha1sssssss");
        stringBuffer.append(new Date().getTime());
        roleDto.setName(stringBuffer.toString());
        roleDao.updateRoleDto(roleDto);
        return false;
    }

    /**
     * 嵌套回滚  https://www.cnblogs.com/duanxz/p/4746892.html
     * @return
     */
    @Override
    @Transactional
    public boolean transactionTest() {
        List<RoleDto> roleDtoList=selectRole();
        RoleDto roleDto= roleDtoList.get(0);
        /*try{
            transactionTest2(roleDto);
        }catch (Exception e){
        }finally {
            System.out.println(roleDto.getId());
        }*/
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("hahha");
        stringBuffer.append(new Date().getTime());
        roleDto.setName(stringBuffer.toString());
        roleDao.updateRoleDto(roleDto);
        int i=2/0;
        return false;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public boolean transactionTest2(RoleDto roleDto){
        roleDto.setId("888888");
        int i=2/0;
        return false;
    }


    @Override
    @Transactional
    public boolean jmsTransactionTest() {
        MessageCreator messageCreator=new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                Message message=session.createMessage();
                message.setStringProperty("hello","hello,Jms");
                return message;
            }
        };
        jmsTemplate.send("dynamicDestinationResolver",messageCreator);
        transactionTest();
        return false;
    }
}

接收消息侦听器

package com.hua.fileplat.cloud.base.jms;

import com.hua.fileplat.cloud.user.service.RoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.transaction.annotation.Transactional;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;

/**
 * JSM 接收消息侦听
 */
public class JmsReceiveListener implements SessionAwareMessageListener {

    @Autowired
    private RoleService roleService;
    /**
     * 日志
     */
    Logger logger= LoggerFactory.getLogger(JmsReceiveListener.class);
    @Override
    @Transactional
    public void onMessage(Message message, Session session) {
        try {
            logger.info("接收消息内容为:"+message.getStringProperty("hello"));
            roleService.transactionTest1();
            int i=10/0;
        }catch (JMSException e){
            e.printStackTrace();
            logger.error("接收消息异常编号:"+e.getErrorCode()+" 异常信息:"+e.getMessage());
            try {
                session.rollback();
            } catch (JMSException e1) {
                logger.error(" 事务异常信息:"+e.getMessage());
            }
        }

    }
}

注:

  1. 如果 发送消息 所在的方法 出现了 异常 那么 消息不会被发送出去
  2. 如果 接收消息 出现了异常 ,那么 事务也会回滚,数据库也不会执行更新操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值