(二)在项目中如何使用ActiveMQ的具体用法(一些常见的踩坑)?

本文详细介绍如何在项目中使用ActiveMQ消息队列,包括选择点对点或发布订阅模式,封装发送方法,以及如何监听Queue或Topic。特别关注BytesMessage类型的应用,包括序列化与反序列化过程。
摘要由CSDN通过智能技术生成

(1)首先一般在项目中的使用无非不就是把消息发送到ActiveMQ中的消息队列中去,先要考虑是使用点对点的模式,还是使用topic发布订阅的模式来进行发送的。然后就是结合自己的业务,看你放到ActiveMQ中的是什么类型的数据,然后采用不同的Message类型

  1. TextMessage
  2. MapMessage
  3. BytesMessage(我这里项目中采用的是字节数组类型的)
  4. StreamMessage
  5. ObjectMessage

(2)然后其实就是封装send方法,当然你可以用Jmstemeplate这个模板类型来进行使用原生的API,但是我这里是自己封装的sendMessage()方法,封装到ActiveMQService类中,用的时候直接注入ActiveMQService这个类就行了


/**
 * @FileName: ActiveMqService.java
 * @Description: ActiveMqService.java类说明
 * @Author: admin
 * @Date: 2019/5/31 11:56
 */
@Slf4j
@Service
public class ActiveMqServiceImpl implements ActiveMqService{


    @Value("${spring.activemq.broker-url}")
    private  String mBrokerURL;
    @Value("${spring.activemq.user}")
    private   String user;
    @Value("${spring.activemq.password}")
    private  String password;

    @Override
    public Boolean sendMessage(String destinationName, ActiveMqTask activeMqTaskData) {
        MessageProducer producer = null;
        Session session = null;
       try {
           session = getSession();
           Destination destination = session.createQueue(destinationName);
           log.info("发送到MQ的目的队列为:{}",destinationName);
           producer = session.createProducer(destination);
           BytesMessage message = session.createBytesMessage();
           byte[] data = objectToBytes(activeMqTaskData);
           message.writeBytes(data);
           producer.send(message);
           log.info("发送到:{}消息队列中成功!",destinationName);
       }catch (Exception e){
           log.info("发送到:{}消息队列异常失败!",destinationName);
           return false;
       }finally {
           if(producer != null){
               try {
                   producer.close();
                   log.info("关闭生产者");
               } catch (JMSException e) {
                   e.printStackTrace();
               }
           }
           if(session != null){
               try {
                   session.close();
                   log.info("关闭session连接");
               } catch (JMSException e) {
                   e.printStackTrace();
               }
           }
       }
        return true;
    }

    /**
     * @Author: wangwei
     * @Description: 这个是用来封装获取session的方法
     * @Param:  * @Param: null
     * @Date: 2019-06-04
     */
    public  Session getSession(){
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,mBrokerURL);
        Connection connection = null;
        Session session = null;
        try {
            connection = connectionFactory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        } catch (JMSException e) {
            log.info("没有成功连接到ActiveMQ的服务器");
            e.printStackTrace();
        }
        log.info("从connection获取session成功!");
        return session;
    }

    /**
     * @Author: wangwei
     * @Description: 把消息对象转为byte数组进行传输
     * @Param:  * @Param: null
     * @Date: 2019-06-04
     */
    public  byte[] objectToBytes(ActiveMqTask activeMqTask) throws Exception {
        log.info("把任务名为:{}的对象转换为byte数组",activeMqTask.getName());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream sOut = new ObjectOutputStream(out);
        sOut.writeObject(activeMqTask);
        sOut.flush();
        byte[] bytes = out.toByteArray();
        return bytes;
    }

}

(3)封装好sendMessage方法之后,就是在项目中具体怎么去监听一个ActiveMQ中的Queue或者Topic主题的事件了,这个就是监听的时候使用到的方法

  /**
     * @Author: wangwei
     * @Description: 监听任务进度更新的消息队列
     * @Param: * @Param: null
     * @Date: 2019-06-04
     */
    @JmsListener(destination = "DX_MOBSEC_task_progress_queue")
    public void listerProgressQueueMessage(BytesMessage bytesMessage) {
         TaskProgressBO taskProgressBO = null;
        log.info("*****************************开始监听DX_MOBSEC_task_progress_queue队列中的任务*******************************");
        if (bytesMessage != null) {
            try {
                taskProgressBO = ActiveMqUtils.fromMessageToTaskProgress(bytesMessage);
                if (taskProgressBO != null) {
                    int effectResult = fastenProtectExtendMapper.updTaskProgressById(taskProgressBO);
                    if (effectResult > 0) {
                        log.info("更新任务:{}进度信息成功!", taskProgressBO.getId());
                    } else {
                        log.info("更新任务:{}进度信息失败!", taskProgressBO.getId());
                    }
                }
            } catch (Exception e) {
                log.info("把BytesMessage转为实体的过程中失败!");
            }
        } else {
            log.info("监听到[DX_MOBSEC_task_progress_queue]的BytesMessage类型的信息为NULL");
        }

    }

这个是需要把上面监听到主题的数据内容给转换成你想要的实体对象(因为一般和业务结合的话,这个数据都是放在对象实体中的,因为发送消息的时候使用到的Message类型是BytesMessage类型,所以这里也需要把接收的Message对象转为实体)

  • 这里有几个坑需要注意一下:首先你得知道BytesMessage和TextMessage等等,他们都是继承自Message对象,所以这里的message其实就是指我们接受到的BytesMessage类型
  • 第一个坑就是发送数据使用到的XXXXMessage类型和接收到的Message类型必须要保持一致,不然是接收不到数据的,还会报错
  • 第二个坑就是你的ActiveMQ的brokerUrl的地址是 tcp://10.0.0.203:61616这种的,而不是8161的这种端口,不然会报错 javax.jms.JMSException: Unknown data type: 47
    /**
     * @Author: wangwei
     * @Description: 把消费到的Message信息通过byte[]字节数组过渡到TaskProgressBO对象
     * @Param:  * @Param: null
     * @Date: 2019-06-04
     */
    public static TaskProgressBO fromMessageToTaskProgress(Message message){
        try(ByteArrayOutputStream bos = new ByteArrayOutputStream()){
            byte buff[] = new byte[256];
            int length;
            while((length = ((BytesMessage)message).readBytes(buff)) > 0){
                bos.write(buff, 0, length);
            }
            return ActiveMqUtils.fromBytesToTaskProgress(bos.toByteArray());
        }catch (IOException e){
            e.printStackTrace();
        } catch (JMSException e) {
            e.printStackTrace();
        }
        return null;
    }

把传输过来的字节数组转为TaskProgressBO对象

    /**
     * @Author: wangwei
     * @Description: 把传输过来的字节数组转为TaskProgressBO对象
     * @Param:  * @Param: null
     * @Date: 2019-06-04
     */
    public static TaskProgressBO fromBytesToTaskProgress(byte[] bytes){
        try(ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))){
            return (TaskProgressBO)ois.readObject();
        }catch (IOException | ClassNotFoundException e){
            e.printStackTrace();
        }
        return null;
    }
可以使用以下步骤在Spring Boot项目集成ActiveMQ: 1. 在pom.xml添加ActiveMQ依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> ``` 2. 在application.properties文件添加ActiveMQ配置: ```properties spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin ``` 3. 创建一个消息生产者: ```java import javax.jms.ConnectionFactory; import javax.jms.Queue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsMessagingTemplate; import org.springframework.stereotype.Component; @Component public class MessageProducer { @Autowired private JmsMessagingTemplate jmsMessagingTemplate; @Autowired private Queue queue; public void send(String message) { this.jmsMessagingTemplate.convertAndSend(queue, message); } } ``` 4. 创建一个消息消费者: ```java import javax.jms.Queue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class MessageConsumer { @Autowired private Queue queue; @JmsListener(destination = "${spring.activemq.queue-name}") public void receive(String message) { System.out.println("Received message: " + message); } } ``` 5. 在应用程序使用消息生产者发送消息: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class MyApp implements CommandLineRunner { @Autowired private MessageProducer messageProducer; @Override public void run(String... args) throws Exception { messageProducer.send("Hello, World!"); } } ``` 这样就可以在你的Spring Boot应用程序使用ActiveMQ了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值