ActiveMQ的介绍及使用实例.
今天就来说下 这个项目中使用ActiveMQ的情况, MQ: message queue, 顾名思义就是消息队列的意思.
一: 使用场景:
那么在babasport这个项目中, 我们可以在上架的时候使用消息队列的模式:
我们之前在点击一款商品上架的时候, 我们需要分成2步, 第一: 更新商品表中该商品的上架状态. 第二: 将该商品信息保存到Solr服务器中. 那么如果我们使用了消息队列后, 第二步就可以使用发送message来异步完成.
消息队列可以接收消息和 发送消息
消息队列类型:
队列:一对一聊天 私聊 QQ
主题(订阅模式):一对多聊天 群聊 QQ
名词解释:
二, 代码原型
ActiveMQ需要部署到Linux系统下, 这里就不再做概述.
这里也是tar包, 导入到linux下直接解压启动即可, 前面已经有过很多博文讲Linux下一些常用软件的安装步骤.
上架代码原型:
项目构件图:
未使用ActiveMQ前ProductServiceImpl.cs:
//上架
public void isShow(Long[] ids){
Product product = new Product();
product.setIsShow(true);
for (final Long id : ids) {
//上下架状态
product.setId(id);
productDao.updateByPrimaryKeySelective(product); //这个地方的代码应该在babasport-solr中写, 现在使用ActiveMQ进行迁移.
//TODO 保存商品信息到Solr服务器
SolrInputDocument doc = new SolrInputDocument();
//ID
doc.setField("id", id);
//名称
Product p = productDao.selectByPrimaryKey(id);
doc.setField("name_ik", p.getName());
//图片URL
doc.setField("url", p.getImgUrls()[0]);
//品牌 ID
doc.setField("brandId", p.getBrandId());
//价格 sql查询语句: select price from bbs_sku where product_id = ? order by price asc limit 1
SkuQuery skuQuery = new SkuQuery();
skuQuery.createCriteria().andProductIdEqualTo(id);
skuQuery.setOrderByClause("price asc");
skuQuery.setPageNo(1);
skuQuery.setPageSize(1);
List<Sku> skus = skuDao.selectByExample(skuQuery);
doc.setField("price", skus.get(0).getPrice());
//...时间等 剩下的省略 try {
solrServer.add(doc);
solrServer.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //TODO 静态化
}
}
上面的代码 除了更改本来就该更改的商品状态信息外, 还去见商品信息保存到了Solr服务器中了. 这里我们使用ActiveMQ进行改造:
使用ActiveMQ后的ProductServiceImpl.cs:
//上架
public void isShow(Long[] ids){
Product product = new Product();
product.setIsShow(true);
for (final Long id : ids) {
//上下架状态
product.setId(id);
productDao.updateByPrimaryKeySelective(product); //发送商品ID到ActiveMQ即可.
jmsTemplate.send(new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException { return session.createTextMessage(String.valueOf(id));
}
}); //TODO 静态化
}
}
接着就是配置消息发送方(JMS生产者) mq.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/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 配置Spring 来管理MQ消息队列 , 连接ActiveMQ-->
<!-- 连接工厂, 此工厂由Apache提供 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- 连接地址
在网页端访问是:http://192.168.200.128:8161, 但是这里是tcp连接, 端口号是61616
-->
<property name="brokerURL" value="tcp://192.168.200.128:61616"/>
<!-- 设置用户名及密码 -->
<property name="userName" value="admin"></property>
<property name="password" value="admin"></property>
</bean> <!-- 配置连接池管理工厂 -->
<bean id="pooledConnectionFactoryBean" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<!-- 注入工厂 -->
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<!-- 设置最大连接数 -->
<property name="maxConnections" value="5"></property>
</bean> <!-- 把上面的工厂交给Spring管理 -->
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 注入上面的工厂 -->
<property name="targetConnectionFactory" ref="pooledConnectionFactoryBean"></property>
</bean> <!-- 使用Spring提供的jmsTemplate模板来操作ActiveMQ -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 注入Spring单例工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"></property>
<!-- 设置默认的目标管道 -->
<property name="defaultDestinationName" value="pId"/>
</bean>
</beans>
配置说明: 这里是首先构建一个MQ的连接工厂, 只要ActiveMQ启动后 就可以这样构建连接了. 配置登录的用户名和和密码.
接着就是配置连接池, 把连接工厂交给连接池去管理. 这些都是Apache厂商提供的.
接着就是再将连接池交由Spring管理.
最后我们再来配置一个jmsTemplate模板来操作ActiveMQ, 这个类似于jdbcTemplate模板. 而且我们这个里面注入了一个默认的管道, 也就是productId, 因为我们现在是 传递消息一一去对应, 关于怎么对应 就是依赖于这个管道.
接下来我们就看下消息的接收方(JMS消费者)的一些东西:
消费者的目录结构:(Solr)
Solr项目中的ActiveMQ配置文件mq.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/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 配置Spring 来管理MQ消息队列 , 连接ActiveMQ-->
<!-- 连接工厂, 此工厂由Apache提供 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- 连接地址
在网页端访问是:http://192.168.200.128:8161, 但是这里是tcp连接, 端口号是61616
-->
<property name="brokerURL" value="tcp://192.168.200.128:61616"/>
<!-- 设置用户名及密码 -->
<property name="userName" value="admin"></property>
<property name="password" value="admin"></property>
</bean> <!-- 配置连接池管理工厂 ,由Apache提供.-->
<bean id="pooledConnectionFactoryBean" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<!-- 注入工厂 -->
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<!-- 设置最大连接数 -->
<property name="maxConnections" value="5"></property>
</bean> <!-- 把上面的工厂交给Spring管理 -->
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 注入上面的工厂 -->
<property name="targetConnectionFactory" ref="pooledConnectionFactoryBean"></property>
</bean> <!-- 使用Spring提供的jmsTemplate模板来操作ActiveMQ -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 注入Spring单例工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"></property>
<!-- 设置默认的目标管道 -->
<property name="defaultDestinationName" value="pId"/>
</bean> <!-- 实例化一个监听到消息后 处理此消息的类 -->
<bean id="customMessageListener" class="cn.itcast.core.service.message.CustomMessageListener"/> <!-- 配置实时监听器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!-- 配置工厂, 需要配置spirng的工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"/>
<!-- 设置监听的目标 -->
<property name="destinationName" value="pId"/>
<!-- 监听后获取消息的类, 接收监听到的消息 -->
<property name="messageListener" ref="customMessageListener"></property>
</bean>
</beans>
我们来说下 和上面配置不同的地方, 我们在这里配置了一个监听器, 因为接收到 JMS 生产者发过来的消息后我们需要有个监听器去监听且 将监听到的消息拿过来处理.
接下来看看监听器的处理方法做了些什么事情:
CustomMessageListener.java:
/*
* 接收MQ中的消息
*/
public class CustomMessageListener implements MessageListener{
@Autowired
private SearchService searchService; @Override
public void onMessage(Message message) {
//先将接收到的消息强转为ActiveMQ类型的消息
//因为在消息发送方那边传递的是Text类型的消息对象, 所以需要转成ActiveMQTextMessage
ActiveMQTextMessage amtm = (ActiveMQTextMessage)message;
try {
String id = amtm.getText();
System.out.println("接收到的ID:"+id);
searchService.insertProductToSolr(Long.parseLong(id));
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
因为我们接收到的是string类型的文本, 所以这里我们直接将接收到的消息转换为ActiveMQText类型, 然后通过getText去得到传递过来的id, 然后我们就可以通过这个productId去做相应的操作了.
接下来就看保存商品信息到Solr服务器的逻辑:
SearchServiceImpl.java:
//保存商品信息到Solr服务器中, 通过ActiveMQ
public void insertProductToSolr(Long productId){
//TODO 保存商品信息到Solr服务器
SolrInputDocument doc = new SolrInputDocument();
//ID
doc.setField("id", productId);
//名称
Product p = productDao.selectByPrimaryKey(productId);
doc.setField("name_ik", p.getName());
//图片URL
doc.setField("url", p.getImgUrls()[0]);
//品牌 ID
doc.setField("brandId", p.getBrandId());
//价格 sql查询语句: select price from bbs_sku where product_id = ? order by price asc limit 1
SkuQuery skuQuery = new SkuQuery();
skuQuery.createCriteria().andProductIdEqualTo(productId);
skuQuery.setOrderByClause("price asc");
skuQuery.setPageNo(1);
skuQuery.setPageSize(1);
List<Sku> skus = skuDao.selectByExample(skuQuery);
doc.setField("price", skus.get(0).getPrice());
//...时间等 剩下的省略 try {
solrServer.add(doc);
solrServer.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这样就比较明朗了, ActiveMQ 队列就是这样来实现的.
====================接下来还会有 ActiveMQ 订阅者模式的示例, 这里只是生产者发送消息给单个消费者, 下次还会更新生产者发送消息给多个消费者.
2016/09/04 20:32 更新
上面已经说了 消息的队列模式, 及点对点发送消息, 那么接下来就来说下 消息的一对多模式, 也就是 发布/订阅模式.
项目原型: 当商品上架后(babasport-product), 发送消息id给solr(babasport-solr)来将商品信息保存到solr服务器和cms(babasport-cms)来对商品详情页面做页面静态化.
===================
babasport-product:
结构图:
babasport-product下的项目结构图:
ProductServiceImpl.java中的上架:
@Autowired
private JmsTemplate jmsTemplate; //上架
public void isShow(Long[] ids){
Product product = new Product();
product.setIsShow(true);
for (final Long id : ids) {
//上下架状态
product.setId(id);
productDao.updateByPrimaryKeySelective(product); //发送商品ID到ActiveMQ即可.
jmsTemplate.send(new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException { return session.createTextMessage(String.valueOf(id));
}
});
}
}
mq.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/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 配置Spring 来管理MQ消息队列 , 连接ActiveMQ-->
<!-- 连接工厂, 此工厂由Apache提供 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- 连接地址
在网页端访问是:http://192.168.200.128:8161, 但是这里是tcp连接, 端口号是61616
-->
<property name="brokerURL" value="tcp://192.168.200.128:61616"/>
<!-- 设置用户名及密码 -->
<property name="userName" value="admin"></property>
<property name="password" value="admin"></property>
</bean> <!-- 配置连接池管理工厂 -->
<bean id="pooledConnectionFactoryBean" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<!-- 注入工厂 -->
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<!-- 设置最大连接数 -->
<property name="maxConnections" value="5"></property>
</bean> <!-- 把上面的工厂交给Spring管理 -->
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 注入上面的工厂 -->
<property name="targetConnectionFactory" ref="pooledConnectionFactoryBean"></property>
</bean> <!-- 使用Spring提供的jmsTemplate模板来操作ActiveMQ -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 注入Spring单例工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"></property>
<!-- 设置默认的目标管道 -->
<property name="defaultDestinationName" value="pId"/>
<!-- 默认是队列模式, 可改为主题, 发布模式 publish subject -->
<property name="pubSubDomain" value="true"/>
</bean>
</beans>
这里面的最大的变化就是将消息发布模式改为了: publish subject.
============================================
babasport-solr:
mq.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/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 配置Spring 来管理MQ消息队列 , 连接ActiveMQ-->
<!-- 连接工厂, 此工厂由Apache提供 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- 连接地址
在网页端访问是:http://192.168.200.128:8161, 但是这里是tcp连接, 端口号是61616
-->
<property name="brokerURL" value="tcp://192.168.200.128:61616"/>
<!-- 设置用户名及密码 -->
<property name="userName" value="admin"></property>
<property name="password" value="admin"></property>
</bean> <!-- 配置连接池管理工厂 ,由Apache提供.-->
<bean id="pooledConnectionFactoryBean" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<!-- 注入工厂 -->
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<!-- 设置最大连接数 -->
<property name="maxConnections" value="5"></property>
</bean> <!-- 把上面的工厂交给Spring管理 -->
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 注入上面的工厂 -->
<property name="targetConnectionFactory" ref="pooledConnectionFactoryBean"></property>
</bean> <!-- 使用Spring提供的jmsTemplate模板来操作ActiveMQ -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 注入Spring单例工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"></property>
<!-- 设置默认的目标管道 -->
<property name="defaultDestinationName" value="pId"/>
</bean> <!-- 实例化一个监听到消息后 处理此消息的类 -->
<bean id="customMessageListener" class="cn.itcast.core.service.message.CustomMessageListener"/> <!-- 配置实时监听器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!-- 配置工厂, 需要配置spirng的工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"/>
<!-- 设置监听的目标 -->
<property name="destinationName" value="pId"/>
<!-- 监听后获取消息的类, 接收监听到的消息 -->
<property name="messageListener" ref="customMessageListener"></property>
<!-- 默认是队列模式, 可改为主题, 发布模式 publish subject -->
<property name="pubSubDomain" value="true"/>
</bean>
</beans>
SearchServiceImpl.java: 保存商品信息到Solr服务器中, 通过ActiveMQ
//保存商品信息到Solr服务器中, 通过ActiveMQ
public void insertProductToSolr(Long productId){
//TODO 保存商品信息到Solr服务器
SolrInputDocument doc = new SolrInputDocument();
//ID
doc.setField("id", productId);
//名称
Product p = productDao.selectByPrimaryKey(productId);
doc.setField("name_ik", p.getName());
//图片URL
doc.setField("url", p.getImgUrls()[0]);
//品牌 ID
doc.setField("brandId", p.getBrandId());
//价格 sql查询语句: select price from bbs_sku where product_id = ? order by price asc limit 1
SkuQuery skuQuery = new SkuQuery();
skuQuery.createCriteria().andProductIdEqualTo(productId);
skuQuery.setOrderByClause("price asc");
skuQuery.setPageNo(1);
skuQuery.setPageSize(1);
List<Sku> skus = skuDao.selectByExample(skuQuery);
doc.setField("price", skus.get(0).getPrice());
//...时间等 剩下的省略 try {
solrServer.add(doc);
solrServer.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
CustomMessageListener.java: 监听ActiveMQ中传递过来的消息, 且对传递过来的消息进行处理:
public class CustomMessageListener implements MessageListener{
@Autowired
private SearchService searchService; @Override
public void onMessage(Message message) {
//先将接收到的消息强转为ActiveMQ类型的消息
//因为在消息发送方那边传递的是Text类型的消息对象, 所以需要转成ActiveMQTextMessage
ActiveMQTextMessage amtm = (ActiveMQTextMessage)message;
try {
String id = amtm.getText();
System.out.println("接收到的ID:"+id);
searchService.insertProductToSolr(Long.parseLong(id));
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
===============================
babasport-cms:
mq.xml:
<!-- 配置Spring 来管理MQ消息队列 , 连接ActiveMQ-->
<!-- 连接工厂, 此工厂由Apache提供 -->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- 连接地址
在网页端访问是:http://192.168.200.128:8161, 但是这里是tcp连接, 端口号是61616
-->
<property name="brokerURL" value="tcp://192.168.200.128:61616"/>
<!-- 设置用户名及密码 -->
<property name="userName" value="admin"></property>
<property name="password" value="admin"></property>
</bean> <!-- 配置连接池管理工厂 ,由Apache提供.-->
<bean id="pooledConnectionFactoryBean" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<!-- 注入工厂 -->
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<!-- 设置最大连接数 -->
<property name="maxConnections" value="5"></property>
</bean> <!-- 把上面的工厂交给Spring管理 -->
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 注入上面的工厂 -->
<property name="targetConnectionFactory" ref="pooledConnectionFactoryBean"></property>
</bean> <!-- 使用Spring提供的jmsTemplate模板来操作ActiveMQ -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 注入Spring单例工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"></property>
<!-- 设置默认的目标管道 -->
<property name="defaultDestinationName" value="pId"/>
</bean> <!-- 实例化一个监听到消息后 处理此消息的类 -->
<bean id="customMessageListener" class="cn.itcast.core.service.message.CustomMessageListener"/> <!-- 配置实时监听器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!-- 配置工厂, 需要配置spirng的工厂 -->
<property name="connectionFactory" ref="singleConnectionFactory"/>
<!-- 设置监听的目标 -->
<property name="destinationName" value="pId"/>
<!-- 监听后获取消息的类, 接收监听到的消息 -->
<property name="messageListener" ref="customMessageListener"></property>
<!-- 默认是队列模式, 可改为主题, 发布模式 publish subject -->
<property name="pubSubDomain" value="true"/>
</bean>
CustomMessageListener.java: 监听ActiveMQ中传递过来的消息, 且对传递过来的消息进行处理:
public class CustomMessageListener implements MessageListener{
@Autowired
private StaticPageService staticPageService;
@Autowired
private CMSService cmsService; @Override
public void onMessage(Message message) {
//先将接收到的消息强转为ActiveMQ类型的消息
//因为在消息发送方那边传递的是Text类型的消息对象, 所以需要转成ActiveMQTextMessage
ActiveMQTextMessage amtm = (ActiveMQTextMessage)message;
try {
String id = amtm.getText();
System.out.println("CMS接收到的ID:"+id);
Map<String, Object> root = new HashMap<String, Object>(); Product product = cmsService.selectProductById(Long.parseLong(id));
List<Sku> skus = cmsService.selectSkuListByProductIdWithStock(Long.parseLong(id));
//去掉重复的颜色
Set<Color> colors = new HashSet<Color>();
for (Sku sku : skus) {
colors.add(sku.getColor());
}
root.put("colors", colors);
root.put("product", product);
root.put("skus", skus); staticPageService.index(root, id);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
StaticPageServiceImpl.java: 静态化页面的核心类:
public class StaticPageServiceImpl implements StaticPageService, ServletContextAware{
//SpringMvc 管理 conf
private Configuration conf;
public void setFreeMarkerConfig(FreeMarkerConfig freeMarkerConfig) {
this.conf = freeMarkerConfig.getConfiguration();
} //静态化页面的方法
public void index(Map<String, Object> root, String id){
//输出目录: 通过getPath方法获取的是绝对路径
String path = getPath("/html/product/" + id +".html");
File f = new File(path);
File parentFile = f.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
} //spring中已经设置了模板路径:<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
Writer out = null; try {
//读
Template template = conf.getTemplate("product.html"); //设置输出的位置
//写
out = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");
template.process(root, out);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (out != null)
{
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } } //获取webapp下的html文件夹所在的位置
//将相对路径转换为绝对路径
public String getPath(String path){
return servletContext.getRealPath(path);
} private ServletContext servletContext;
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
Spring管理 freemarkerConfig配置类:
<!-- 配置freemarker 实现类 -->
<bean class="cn.itcast.core.service.StaticPageServiceImpl">
<property name="freeMarkerConfig">
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 设置模板所在目录或文件夹的位置, 相对路径 -->
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<!-- 设置默认编码集 -->
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
</property>
</bean>
更多关于freemarker的讲解请关注我以后的博客...
关于ActiveMQ的内容就更新到这么多.
ActiveMQ的介绍及使用实例.的更多相关文章
- Java XML解析工具 dom4j介绍及使用实例
Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...
- [转] 引用 Java自带的线程池ThreadPoolExecutor详细介绍说明和实例应用
PS: Spring ThreadPoolTaskExecutor vs Java Executorservice cachedthreadpool 引用 [轰隆隆] 的 Java自带的线程池Thre ...
- Linux Epoll介绍和程序实例
Linux Epoll介绍和程序实例 1. Epoll是何方神圣? Epoll但是当前在Linux下开发大规模并发网络程序的热门人选,Epoll 在Linux2.6内核中正式引入,和select类似, ...
- React Native之FlatList的介绍与使用实例
React Native之FlatList的介绍与使用实例 功能简介 FlatList高性能的简单列表组件,支持下面这些常用的功能: 完全跨平台. 支持水平布局模式. 行组件显示或隐藏时可配置回调事件 ...
- activemq概念介绍
ActiveMQ概念介绍 是Apache下的开源项目,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现,消息中间件. 消息中间件: A传递消息到B(功能或者系统),有比较强的耦合 ...
- ActiveMQ使用介绍及实例
上一篇讲了rabbitmq的使用以及demo,activemq的思路也与之有相似的地方. activemq是基于Java实现的.activemq没有rabbitmq那么多的路由规则,其通信方式只有两种 ...
- 深入浅出JMS(二)--ActiveMQ简单介绍以及安装
现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 上篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了消息通信的规范JM ...
- JMS【二】--ActiveMQ简单介绍以及安装
现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 上篇博文JMS[一]--JMS基本概念,我们介绍了消息通信的规范JMS,我 ...
- ActiveMQ简单介绍以及安装
概述 首先简单的介绍一下MQ,MQ英文名MessageQueue,中文名也就是大家用的消息队列,干嘛用的呢,说白了就是一个消息的接受和转发的容器,可用于消息推送. ActiveMQ是Apache所提供 ...
随机推荐
- VBA实例收集
1.工作表事件:固定制定区域激活,使之不能选择其他区域. Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target. ...
- HDU5937 Equation(DFS + 剪枝)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5937 Description Little Ruins is a studious boy, ...
- Set和存储顺序
set(interface) 存入Set的每个元素必须是唯一的,因为Set不保存重复的元素.加入Set的元素必须定义 equal()方法以确保对象的唯一性.Set和Collection有完全一样的接口 ...
- 【BZOJ3943】[Usaco2015 Feb]SuperBull 最小生成树
[BZOJ3943][Usaco2015 Feb]SuperBull Description Bessie and her friends are playing hoofball in the an ...
- SVG文件:从Illustrator导文件到Web
可缩放矢量图形(SVG)是早在1998年就已经有的一种矢量图像格式.它总是和Web一起发展,但是直到现在才开始赶上Web发展的步伐.如今我们已经不能否认SVG和Web的相关性,所以让我们来学习一下从I ...
- 在Andoid开发中使用MVP模式来解耦,增加可测试性
by Jeff Angelini posted on 7/20/2011 2:35:00 PM 将应用程序UI的表现从Ui的逻辑中分离是一个好的想法.这种分离减少了代码耦合,代码更加干净, 甚至可以有 ...
- LINUX下编译安装PHP各种报错大集合
本文为大家整理汇总了一些linux下编译安装php各种报错大集合 ,感兴趣的同学参考下. nginx1.6.2-mysql5.5.32二进制,php安装报错解决: 123456 [root@clien ...
- 开启PHP的伪静态
1.检测Apache是否支持mod_rewrite 通过php提供的phpinfo()函数查看环境配置,通过Ctrl+F查找到“Loaded Modules”,其中列出了所有 apache2handl ...
- sql 更新列表中最老的一条数据
今天组长给个任务说要给摄像头触发一个列表.让缓存5条数据,每次摄像头触发更新一条,丢掉最老的一条数据.原来的update是直接更新掉一条,没带缓存的.然后搞了个sql语句,是这样的: UPDATE C ...
- Python模块之常用模块,反射以及正则表达式
常用模块 1. OS模块 用于提供系统级别的操作,系统目录,文件,路径,环境变量等 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("di ...