ActiveMQ(artemis版) 基本安装与Spring JMS基本使用

引言

使用artemis版本MQ。Spring JMS 使用springframework-mvc架构,传统xml配置,部署到tomcat运行。如果采用springboot将更简单。有空将更新成springboot

ActiveMQ基本安装与使用

注: ActiveMQ下载的artemis版本,与之前的ActiveMQ版本有点区别,

下载ActiveMQ

下载地址 https://activemq.apache.org/index.html

ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第1张图片ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第2张图片## 安装ActiveMQ

  1. apache-artemis-2.11.0.bin.tar.gz解压该文件
  2. 进入cd apache-artemis-2.11.0/bin目录
  3. 运行一下脚本,创建一个实例,自动在software目录下生成一个myInstance目录,
./artemis create /Users/somnus/Documents/software/myInstance
# ./artemis create /Users/somnus/Documents/software/myInstance

ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第3张图片

  1. 运行activemq
cd ./artemis create /Users/somnus/Documents/software/myInstance/bin
./artemis run  #运行activemq

ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第4张图片5.通过浏览器访问activemq控制台
地址 http://localhost:8161/
ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第5张图片6. 进入控制台Management Console
路径:http://localhost:8161/console/login,记不住,直接http://localhost:8161通过点击进入

ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第6张图片
ActiveMQ(artemis版) 基本安装与Spring JMS基本使用_第7张图片

Spring JMS项目

项目POM配置

 <dependencies>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.2.4.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.10.3version>
        dependency>
        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>4.0.1version>
            <scope>providedscope>
        dependency>
        
        <dependency>
            <groupId>org.apache.activemqgroupId>
            <artifactId>artemis-jms-clientartifactId>
            <version>2.11.0version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jmsartifactId>
            <version>5.2.4.RELEASEversion>
        dependency>

    dependencies>

web.xml配置


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">



    




    <servlet>
        <servlet-name>appservlet-name>
        
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <load-on-startup>1load-on-startup>
    servlet>

    <servlet-mapping>
        <servlet-name>appservlet-name>
        <url-pattern>/*url-pattern>
    servlet-mapping>
web-app>

springmvc配置

配置文件名:app-servlet.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
        <mvc:component-scan base-package="com.teachayu.activemq" />

        
        <bean id="connectionFactory" class="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory" />

        
        <bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
                <property name="targetConnectionFactory" ref="connectionFactory"/>
        bean>

        
        <bean id="messageConverter" class="org.springframework.jms.support.converter.MappingJackson2MessageConverter" >
                <property name="typeIdPropertyName" value="test" />
                <property name="typeIdMappings" >
                        <map>
                                <entry key="test" value="com.teachayu.activemq.controller.UserEntity"/>
                        map>
                property>
        bean>
        
        <bean id="pointJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
                <constructor-arg ref="connectionFactory">constructor-arg>
                
                <property name="defaultDestinationName" value="test"/>
                <property name="messageConverter"  ref="messageConverter"/>
                
                
                <property name="pubSubDomain" value="false" />
        bean>
        
        <bean id="receiveListener" class="com.teachayu.activemq.controller.TextReceiveListener">bean>
        
        <bean id="defaultMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
                <property name="messageListener" ref="receiveListener"/>
                <property name="messageConverter" ref="messageConverter"/>
                <property name="destinationName" value="test"/>
                <property name="connectionFactory" ref="connectionFactory"/>
        bean>

        
        <bean id="pojoMessageConverter" class="com.teachayu.activemq.controller.PojoMessageConverter"/>
        
        <bean id="pojoJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
                <constructor-arg ref="connectionFactory">constructor-arg>
                
                <property name="defaultDestinationName" value="test"/>
                <property name="messageConverter"  ref="pojoMessageConverter"/>
                
                
                <property name="pubSubDomain" value="false" />
        bean>
        
        <bean class="com.teachayu.activemq.controller.Pojo1ReceiveListener" id="pojo1ReceiveListener"/>
        
        
        
        <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer" >
                <property name="connectionFactory" ref="connectionFactory"/>
                <property name="destinationName" value="pojo1"/>
                <property name="messageConverter" ref="pojoMessageConverter"/>
                <property name="messageListener" ref="pojo1ReceiveListener"/>
        bean>

        
        <bean id="pubJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
                <property name="connectionFactory" ref="cachingConnectionFactory"/>
                
                <property name="defaultDestinationName" value="pub"/>
                <property name="messageConverter"  ref="pojoMessageConverter"/>
                
                
                <property name="pubSubDomain" value="true" />
        bean>
        
        <bean class="com.teachayu.activemq.controller.Subscribe1Listener" id="subscribe1Listener"/>
        
        <bean class="com.teachayu.activemq.controller.Subscribe2Listener" id="subscribe2Listener"/>
        <bean id="listenerContainer1" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
                
                <property name="pubSubDomain" value="true"/>
                <property name="destinationName" value="pub"/>
                <property name="messageListener" ref="subscribe1Listener"/>
                <property name="messageConverter" ref="pojoMessageConverter"/>
                <property name="connectionFactory" ref="cachingConnectionFactory"/>
        bean>
        <bean id="listenerContainer2" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
                
                <property name="pubSubDomain" value="true"/>
                <property name="messageListener" ref="subscribe2Listener"/>
                <property name="messageConverter" ref="pojoMessageConverter"/>
                <property name="destinationName" value="pub"/>
                <property name="connectionFactory" ref="cachingConnectionFactory"/>
        bean>
        
        
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
                <property name="messageConverters">
                        <list>
                                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                                        <property name="supportedMediaTypes">
                                                <list><value>text/html;charset=UTF-8value>
                                                      <value>application/json;charset=UTF-8value>
                                                list>
                                        property>
                                bean>
                        list>
                property>
        bean>

beans>

消息转换器 与实体类

定义PojoMessageConverter消息转换器,将Object转成ObjectMessage消息,或将ObjectMessage消息转成Object。Object将实现Serializable接口

package com.teachayu.activemq.controller;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import java.io.Serializable;
public class PojoMessageConverter implements MessageConverter {
     
    @Override
    public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
     
        return session.createObjectMessage((Serializable) object);

    }
    @Override
    public Object fromMessage(Message message) throws JMSException, MessageConversionException {
     
        return ((ObjectMessage)message).getObject();
    }
}

实体类,用于测试

package com.teachayu.activemq.controller;
import java.io.Serializable;
public class UserEntity implements Serializable {
     
    private String name;
    private int age;
    private String address;
    public String getName() {
     
        return name;
    }
    public void setName(String name) {
     
        this.name = name;
    }
    public int getAge() {
     
        return age;
    }
    public void setAge(int age) {
     
        this.age = age;
    }
    public String getAddress() {
     
        return address;
    }
    public void setAddress(String address) {
     
        this.address = address;
    }
    @Override
    public String toString() {
     
        return "UserEntity{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

生产者

发送消息与发布消息,通过http://localhost:8080/activemq/send 完成简单消息推送

package com.teachayu.activemq.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * 使用Point-to-Point模式发送消息
 * 使用Publish/Subscribe 模式发布消息
 */
@RestController
public class ProducerController {
     
    /**
     * 发送文本消息模板 Point-to-Point
     * MappingJackson2MessageConverter转换器
     */
    private JmsTemplate jmsTemplate;

    /**
     * 发送对象消息 Point-to-Point
     * PojoMessageConverterz转换器
     */
    private JmsTemplate pojoJmsTemplate;

    /**
     * 发布对象消息  Publish/Subscribe
     * PojoMessageConverterz转换器
     */
    private JmsTemplate pubJmsTemplate;
    @RequestMapping("/send")
    public String send(){
     
        /**
         *  Point-to-Point 模式
         *  使用默认队列发送消息
         *  使用JmsTemplate同步接收
         */

        jmsTemplate.send(new MessageCreator() {
     
            @Override
            public Message createMessage(Session session) throws JMSException {
     
                //发送TextMessage消息
                return  session.createTextMessage("text队列发送消息(接收同步):"+System.currentTimeMillis());
            }
        });
        /**
         * Point-to-Point 模式
         * 使用默认队列发送消息
         * 异步接收 MessageListener
         */
        jmsTemplate.send("text1", new MessageCreator() {
     
            @Override
            public Message createMessage(Session session) throws JMSException {
     
                //发送TextMessage消息
                return  session.createTextMessage("text1队列发送消息(接收异步)"+System.currentTimeMillis());
            }
        });

        /**
         * Point-to-Point  模式
         * 使用定义的转换器
         *  org.springframework.jms.support.converter.MappingJackson2MessageConverter
         *  使用pojo队列发送消息
         *  使用JmsTemplate同步接收
         */
        UserEntity userEntity = new UserEntity();
        long l = System.currentTimeMillis();
        userEntity.setName("张三"+l);
        userEntity.setAddress("地址"+l);
        userEntity.setAge(1);
        jmsTemplate.convertAndSend("pojo",userEntity);

        /**
         * Point-to-Point 模式
         * 使用定义的转换器 com.teachayu.activemq.controller.PojoMessageConverter
         * 使用pojo队列发送消息
         * 异步接收 MessageListener
         */
        userEntity = new UserEntity();
        l = System.currentTimeMillis();
        userEntity.setName("张三"+l);
        userEntity.setAddress("地址"+l);
        userEntity.setAge(1);
        pojoJmsTemplate.convertAndSend("pojo1",userEntity);

        /**
         * Publish/Subscribe 模式
         * 发布消息
         * 默认队列 pub  ,配置文件中
         */
        userEntity = new UserEntity();
        l = System.currentTimeMillis();
        userEntity.setName("张三"+l);
        userEntity.setAddress("地址"+l);
        userEntity.setAge(1);
        pubJmsTemplate.convertAndSend("pub",userEntity);

        return "hello";
    }

    @Autowired
    @Qualifier("pointJmsTemplate")
    public void setJmsTemplate(JmsTemplate jmsTemplate) {
     
        this.jmsTemplate = jmsTemplate;
    }

    @Autowired
    @Qualifier("pojoJmsTemplate")
    public void setPojoJmsTemplate(JmsTemplate pojoJmsTemplate) {
     
        this.pojoJmsTemplate = pojoJmsTemplate;
    }

    @Autowired
    @Qualifier("pubJmsTemplate")
    public void setPubJmsTemplate(JmsTemplate pubJmsTemplate) {
     
        this.pubJmsTemplate = pubJmsTemplate;
    }
}


同步消费者

同步接收消息,是阻塞模式,通过http://localhost:8080/activemq/receive接收消息。
注意:一定要先执行send请求,完成消费发送,不是receive请求将阻塞

package com.teachayu.activemq.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.jms.JMSException;
import javax.jms.TextMessage;

/**
 * 阻塞模式接收消息
 */
@RestController
public class CustomerController {
     

    private JmsTemplate jmsTemplate;
    @RequestMapping("receive")
    public UserEntity receive() throws JMSException {
     
        //阻塞接收消息,默认队列,队列中无消息将阻塞
        TextMessage message = (TextMessage)jmsTemplate.receive();
        System.out.println("接收test队列:"+message.getText());
        //阻塞接收消息,pojo队列,队列中无消息将阻塞
        UserEntity userEntity = (UserEntity)jmsTemplate.receiveAndConvert("pojo");
        System.out.println("接收pojo队列消息"+ userEntity);
        return userEntity;

    }
    @Autowired
    @Qualifier("pointJmsTemplate")
    public void setJmsTemplate(JmsTemplate jmsTemplate) {
     
        this.jmsTemplate = jmsTemplate;
    }
}

异步接收消息,监听模式

采用监听模式接收消息,有消息来将自动获取消息

文本消息接收

package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
 * 监听接收消息
 */
public class TextReceiveListener implements MessageListener {
     
    @Override
    public void onMessage(Message message) {
     
        try {
     
            String text = ((TextMessage) message).getText();
            System.out.println("接收到test队列消息:"+text);
        } catch (JMSException e) {
     
            e.printStackTrace();
        }

    }
}

对象消息接收

package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
/**
 * 队列监听器 pojo1队列
 * PojoMessageConverter完成转换
 */
public class Pojo1ReceiveListener implements MessageListener {
     
    @Override
    public void onMessage(Message message) {
     
        try {
     
            UserEntity userEntity = (UserEntity)  ((ObjectMessage) message).getObject();
            System.out.println("接收pojo1队列消息:"+ message);
        } catch (Exception e) {
     
            e.printStackTrace();
        }
    }
}

订阅消息 监听模式

Subscribe1Listener 订阅pub主题消息

package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
/**
 * 订阅消息
 */
public class Subscribe1Listener implements MessageListener {
     
    @Override
    public void onMessage(Message message) {
     
        UserEntity userEntity = null;
        try {
     
            userEntity = (UserEntity) ((ObjectMessage) message).getObject();
        } catch (JMSException e) {
     
            e.printStackTrace();
        }
        System.out.println("Subscribe1Listener订阅pub队列消息:" + userEntity);
    }
}

Subscribe2Listener 订阅pub主题消息

package com.teachayu.activemq.controller;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
/**
 * 订阅消息
 */
public class Subscribe2Listener implements MessageListener {
     
    @Override
    public void onMessage(Message message) {
     
        UserEntity userEntity = null;
        try {
     
            userEntity = (UserEntity) ((ObjectMessage) message).getObject();
        } catch (JMSException e) {
     
            e.printStackTrace();
        }
        System.out.println("Subscribe2Listener订阅pub队列消息:" + userEntity);
    }
}

测试

前提是运行activemq与springJMS项目,将可以进行以下测试。测试就不截图了。

发送消息

通过浏览器访问 http://localhost:8080/activemq/send 将完成所有消息发送。

接收消息

  1. 采用MessageListener方式在控制台自动打印接收到消息
  2. 通过访问http://localhost:8080/activemq/receive接收text与pojo队列消息

参考资料

https://docs.spring.io/spring/docs/5.2.5.RELEASE/spring-framework-reference/integration.html#remoting-jms

http://localhost:8161/user-manual/index.html #该地址是安装activemq之后访问可以看到。
或者通过以下官网地址查看文档
https://activemq.apache.org/components/artemis/documentation/

你可能感兴趣的:(spring,activemq,activemq,spring,java)