ActiveMQ实现消息队列

实现消息队列

  • rabbitMq
  • rocketMq
  • redis
  • activeMq
  • pom所需要的jar包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    <!-- 从阿里云仓库下载 -->
    <repositories>
    <repository>
    <id>public</id>
    <name>aliyun nexus</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <releases>
    <enabled>true</enabled>
    </releases>
    </repository>
    </repositories>
    <!-- 相关jar包版本号 -->
    <properties>
    <!-- spring版本号 -->
    <spring.version>4.3.7.RELEASE</spring.version>
    <!-- mybatis版本号 -->
    <mybatis.version>3.4.2</mybatis.version>
    <mybatis-spring-version>1.3.0</mybatis-spring-version>
    <!-- log4j日志文件管理包版本 -->
    <slf4j.version>1.7.7</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.apache.xbean</groupId>
    <artifactId>xbean-spring</artifactId>
    <version>3.16</version>
    </dependency>
    <dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-core</artifactId>
    <version>5.7.0</version>
    </dependency>
    <dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-pool</artifactId>
    <version>5.12.1</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <!-- spring核心包 -->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-oxm</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <!-- aop -->
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.10</version>
    </dependency>
    <!-- log start -->
    <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>${log4j.version}</version>
    </dependency>
    <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
    </dependency>
    <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
    </dependency>
    <!-- log end -->
    </dependencies>

    2.新建spring配置文件,进行spring连接activemq的配置
  • spring 的配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
    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.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/jms
    http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
    http://activemq.apache.org/schema/core
    http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd">

    <!-- 自动扫描 -->
    <context:component-scan base-package="com.active" />

    <!-- mq相关配置 -->
    <!--
    1.配置activemq的连接属性,可以产生消息队列的连接
    id属性:为连接工厂起个名字
    brokerURL属性:消息队列服务的地址
    编写规则 tcp://虚拟机ip地址:61616
    userName,password属性:消息队列的用户名和密码,默认都是admin
    -->
    <amq:connectionFactory
    id="amqConnectionFactory"
    brokerURL="tcp://10.0.152.229:61616"
    userName="admin"
    password="admin" />

    <!-- spring caching 连接工厂
    这个配置可以省略,主要是将产生的连接缓存起来,提升程序运行效率
    这个工厂只是管理amq工厂所生产出的连接
    在程序需要使用amq连接的时候,是从这个缓存工厂中获取
    -->
    <bean id="connectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <!-- 指定一下哪个工厂是真正生产连接的工厂 -->
    <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
    <property name="sessionCacheSize" value="100"></property>
    </bean>

    <!-- jms java message service java消息服务 -->
    <!--
    Spring jms Template
    在程序中使用jmsTemplate 来完成对消息队列的一系列相关操作
    -->
    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"></property>
    <!--
    消息队列的模式 取值范围 true false 默认是false
    false 代表了是 生产者/消费者 模式
    true 代表了是 发布者/订阅者 模式
    -->
    <!-- <property name="pubSubDomain" value="false"></property> -->
    <property name="pubSubDomain" value="true"></property>
    </bean>

    <!--
    创建一个队列
    queue 队列 生产者/消费者
    topic 主题 发布者/订阅者
    -->
    <bean id="myQueue" class="org.apache.activemq.command.ActiveMQQueue">
    <!-- 为队列设置一个名字 -->
    <!-- <constructor-arg index="0" value="my-queue" /> -->
    <constructor-arg name="name" value="my-queue" />
    </bean>
    </beans>
  • 3.创建一个生产者类ProviderService(消息发送者)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Service
public class ProviderService {

@Autowired
private JmsTemplate jmsTemplate;

/**
* 与队列相关的类Destination
* 在javax.jms包下
* 在spring配置文件中配置的队列,可以为这个类进行装配
*/
@Autowired
@Qualifier(value="myQueue")
private Destination destination;

/**
* 发送消息方法,方法名字没有具体要求
*/
public void sendMessage(final String msg){
System.out.println("向队列"+destination.toString()+"发送消息***"+msg);

jmsTemplate.send(destination, new MessageCreator() {

public Message createMessage(Session session) throws JMSException {

return session.createTextMessage(msg);

}
});

}
}
  • 4.创建一个消费者类ConsumerService(消息接收者)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Service
public class ComsumerService {

@Autowired
private JmsTemplate jmsTemplate;

/**
* 要跟消息发送者的队列保持一致
*/
@Autowired
@Qualifier(value="myQueue")
private Destination destination;

/**
* 接收消息,方法名没有具体要求
*/
public void receive(){
//这个方法每次会从队列中获取一条消息
TextMessage textMessage = (TextMessage) jmsTemplate.receive(destination);
try {
System.out.println("从队列"+destination.toString()+"收到了消息****"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
  • 5.创建测试类,测试发送消息和接收消息
1
2
3
4
5
6
7
8
9
10
11
12
13
public class TestClass {

public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取消息发送者
ProviderService providerService = (ProviderService) ctx.getBean("providerService");
providerService.sendMessage("哈哈哈哈哈哈哈或或或或或或或");
//获取消息接收者
ComsumerService comsumerService = (ComsumerService)ctx.getBean("comsumerService");
comsumerService.receive();
}

}
  • 测试结果:
    image
  • Springmvc
    image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- ************************** SpringMvc 必要配置  begin  **************************-->

<!-- 自动扫描 记得修改包的路径 -->
<context:component-scan base-package="com.controller"/>

<!-- 视图解析器 记得关注前缀 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!-- 静态资源访问 -->
<mvc:default-servlet-handler/>
<mvc:annotation-driven />
  • 2.在web.xml下增加配置
    如果项目的webapp文件夹下没有WEB-INF文件夹,那么新建一个即可
    在WEB-INF文件夹下创建web.xml文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

<!-- spring相关配置 -->
<!-- 保证在tomcat启动时容器就可以被初始化 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 初始化容器时需要读取配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- spring配置文件的路径 -->
<param-value>classpath*:spring-ioc.xml</param-value>
</context-param>

<!-- 内存清理 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

<!-- 前端控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
  • controller
    image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Controller
public class MqController {

@Autowired
private ProviderService providerService;

@Autowired
private ComsumerService comsumerService;

/**
* 发送消息
* @param msg
* @return
*/
@RequestMapping("/send")
public String send(@RequestParam(value="msg")String msg){
providerService.sendMessage(msg);
return "";
}

/**
* 接收消息
* @return
*/
@RequestMapping("/get")
public String get(){
comsumerService.receive();
return "";
}

}

将项目加入tomcat,并启动,浏览器访问发送和接收,可看到和控制台一样的效果
  • 6.监听者模式

    • 以上的消费者配置是需要手动消息一条消息,什么时候需要接收消息,什么时候调用接收消息的方法即可
      有些情况下,我们需要对一个队列进行监听,有消息进入到队列之后,直接进行消费

      创建一个监听者类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 创建一个队列的监听者
* 有消息进入到队列之后会自动消费
* 需要实现MessageListener接口
* @author muty
*
*/
@Component
public class Listener implements MessageListener{

public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("监听到的内容:"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}

}
}
- 在spring配置文件中对监听者进行配置
1
2
3
4
5
6
7
8
9
<!-- 配置监听者 -->
<bean id="messageListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!-- 连接工厂 监听者 需要获取amq连接 -->
<property name="connectionFactory" ref="connectionFactory" />
<!-- 要监听的队列 写的是跟某一个队列相关的bean标签的id -->
<property name="destination" ref="myQueue" />
<!-- 监听者具体的类 -->
<property name="messageListener" ref="listener" />
</bean>
  • 增加第二个监听者类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

这时,我们在增加一个监听者,并且让两个监听者监听同一个队列
因为当前是生产者,消费者模式,所以 队列在进入了一个消息之后,该消息只能被两个监听者中的其中一个所消费,执行的效果是交替执行

增加第二个监听者类

@Component
public class ListenerTwo implements MessageListener{

public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("第二个类监听到的内容:"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}

}
}
  • 在spring配置文件中对第二个监听者类进行配置
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 配置第二个监听者 -->
<bean id="messageListenerTwo" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!-- 连接工厂 监听者 需要获取amq连接 -->
<property name="connectionFactory" ref="connectionFactory" />
<!-- 要监听的队列 写的是跟某一个队列相关的bean标签的id -->
<property name="destination" ref="myQueue" />
<!-- 监听者具体的类 -->
<property name="messageListener" ref="listenerTwo" />
</bean>

多次运行测试代码查看结果,或者在浏览器向send处理器发送多次请求,
会发送,同一时间,一条消息只能被一个监听者所消费

  • 7.发布者/订阅者模式
1
2
3
4
5
6
7
8
9
10
11
以上,无论是手动接收消息,还是监听者自动消费消息,都是基于生产者/消费者模式

将消息队列的模式更改为发布者/订阅者模式

在spring配置文件中增加一个topic
<!-- 创建一个主题 -->
<bean id="myTopic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="my-topic" />
</bean>

让两个监听者都监听这个topic
  • image

  • 修改发送消息的类,向该topic发送消息
    image

  • 运行测试代码,测试代码还是只发送,不需要接收的代码,因为监听为自动接收
    image

  • 这时运行一次发送消息的代码,两个监听者都可以获取发送的消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值