一、背景介绍

公司自成立以来,一直以做项目为主,算是经累经验吧,自去年以来,我们部门准备将以前的项目做成产品,大概细分了几个小的产品,部们下面又分了几个团队,分别负责产品的研发,而我们属于平台团队,负责公用组件、开发平台的研发。

前期各个项目组使用的技术、框架等都不一样,想把技术、框架统一起来比较困难,并且在早期项目研发的时,各自为战,没有形成合力,有些共性的东西,都是各自做自己的,现在转将项目做成产品时,首先就是要将共性的东西,抽取出来,做成组件,通过SOA架构,将组件的服务和能力暴露出来,提高组件的重用性,例如邮件服务,任务一个产品或者系统通过标准的接口,即可发送邮件,不需要重新编写邮件的代码,短信服务、权限服务等

由于几个项目之间有些数据是共有的,例如人员、组织,HR系统已经有人员、组织的功能,在做其它项目时,人员、组织也需要,例如4A平台,这就需要将人员、组织的数据同步,将来的目标,是由ESB同步,由于时间紧,暂时选择了ActiveMQ的方式,HR系统中的人员、组织的数据项很多,而其它系统需要的很少,可能只需要人员和组织的名称及其标识列,并且数据量不大,不会一次性发送上百个人员或者组织的信息,基于这个考虑,通过将人员、组织信息的数据放在消息内放到消息中件上,各个系统通过订阅的方式获取消息中的数据。

二、实现

1、安装ActiveMQ

到ActiveMQ的官方网站下载ActiveMQ,我下载的5.7.0版,解压,例如D盘,打开bin目录,执行acticemq.bat,启动ActiveMQ。

我是基于spring编写的,新建两个Java工程,将Spring和ActiveMQ的包导入工程中,以下是pom文件:

  1. <dependencies>
  2. <dependency>
  3. <groupId>junit</groupId>
  4. <artifactId>junit</artifactId>
  5. <version>3.8.1</version>
  6. <scope>test</scope>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.springframework</groupId>
  10. <artifactId>spring-jms</artifactId>
  11. <version>4.0.5.RELEASE</version>
  12. </dependency>
  13. <!-- https://mvnrepository.com/artifact/javax.jms/jms -->
  14. <dependency>
  15. <groupId>javax.jms</groupId>
  16. <artifactId>jms</artifactId>
  17. <version>1.1</version>
  18. </dependency>
  19. <!-- https://mvnrepository.com/artifact/log4j/log4j -->
  20. <dependency>
  21. <groupId>log4j</groupId>
  22. <artifactId>log4j</artifactId>
  23. <version>1.2.16</version>
  24. </dependency>
  25.  
  26. <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-core -->
  27.  
  28. <dependency>
  29. <groupId>org.apache.activemq</groupId>
  30. <artifactId>activemq-pool</artifactId>
  31. <version>5.13.0</version>
  32. </dependency>
  33. <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
  34. <dependency>
  35. <groupId>org.apache.activemq</groupId>
  36. <artifactId>activemq-all</artifactId>
  37. <version>5.13.0</version>
  38. </dependency>
  39.  
  40. </dependencies>

2、发送接收的前提

为发送和接收方式,把将要发送的信息封装成对象,分别为用户和组织的对象,包括了用户和组织的信息,我们来看看这两个对象

用户对象,BaseModel是一个基类,封装的用ID,创建人,创建时,最后更新人,最后更新时间,这个对象不再单独列出来

  1. package model;
  2.  
  3. import java.io.Serializable;
  4. import java.util.Date;
  5.  
  6. /**
  7. * 用户对象
  8. *
  9. *
  10. * @author Administrator
  11. * @version $Id$
  12. */
  13. public class JmsFaUser extends BaseModel implements Serializable {
  14. private static final long serialVersionUID = 1L;
  15. private Long id;
  16. private String userNo;
  17. private String userName;
  18. private String userType;
  19. private String identity;
  20. private String region;
  21. private String userStatus;
  22. private String officeEmail;
  23. private String employeeWorkNo;
  24. private Long orgId;
  25. private String description;
  26. private String attribute1;
  27. private String attribute2;
  28. private String attribute3;
  29. private Long OId;
  30. private String userSex;
  31. private String mobileTel;
  32. private String officeTel;
  33. private String selfEmail;
  34. private Date lastUpdatedDate;
  35. // Constructors
  36.  
  37. /** default constructor */
  38. public JmsFaUser() {
  39. }
  40.  
  41. public String getUserNo() {
  42. return this.userNo;
  43. }
  44.  
  45. public void setUserNo(String userNo) {
  46. this.userNo = userNo;
  47. }
  48.  
  49. public String getUserName() {
  50. return this.userName;
  51. }
  52.  
  53. public void setUserName(String userName) {
  54. this.userName = userName;
  55. }
  56.  
  57. public String getUserType() {
  58. return this.userType;
  59. }
  60.  
  61. public void setUserType(String userType) {
  62. this.userType = userType;
  63. }
  64.  
  65. public String getIdentity() {
  66. return this.identity;
  67. }
  68.  
  69. public void setIdentity(String identity) {
  70. this.identity = identity;
  71. }
  72.  
  73. public String getRegion() {
  74. return this.region;
  75. }
  76.  
  77. public void setRegion(String region) {
  78. this.region = region;
  79. }
  80.  
  81. public String getUserStatus() {
  82. return this.userStatus;
  83. }
  84.  
  85. public void setUserStatus(String userStatus) {
  86. this.userStatus = userStatus;
  87. }
  88.  
  89. public String getOfficeEmail() {
  90. return this.officeEmail;
  91. }
  92.  
  93. public void setOfficeEmail(String officeEmail) {
  94. this.officeEmail = officeEmail;
  95. }
  96.  
  97. public String getEmployeeWorkNo() {
  98. return this.employeeWorkNo;
  99. }
  100.  
  101. public void setEmployeeWorkNo(String employeeWorkNo) {
  102. this.employeeWorkNo = employeeWorkNo;
  103. }
  104.  
  105. public String getDescription() {
  106. return this.description;
  107. }
  108.  
  109. public void setDescription(String description) {
  110. this.description = description;
  111. }
  112.  
  113. public String getAttribute1() {
  114. return this.attribute1;
  115. }
  116.  
  117. public void setAttribute1(String attribute1) {
  118. this.attribute1 = attribute1;
  119. }
  120.  
  121. public String getAttribute2() {
  122. return this.attribute2;
  123. }
  124.  
  125. public void setAttribute2(String attribute2) {
  126. this.attribute2 = attribute2;
  127. }
  128.  
  129. public String getAttribute3() {
  130. return this.attribute3;
  131. }
  132.  
  133. public void setAttribute3(String attribute3) {
  134. this.attribute3 = attribute3;
  135. }
  136.  
  137. public String getUserSex() {
  138. return this.userSex;
  139. }
  140.  
  141. public void setUserSex(String userSex) {
  142. this.userSex = userSex;
  143. }
  144.  
  145. /**
  146. * @return the oId
  147. */
  148. public Long getOId() {
  149. return OId;
  150. }
  151.  
  152. /**
  153. * @param oId
  154. * the oId to set
  155. */
  156. public void setOId(Long oId) {
  157. OId = oId;
  158. }
  159.  
  160. public String getSelfEmail() {
  161. return this.selfEmail;
  162. }
  163.  
  164. public void setSelfEmail(String selfEmail) {
  165. this.selfEmail = selfEmail;
  166. }
  167.  
  168. /**
  169. * @param orgId
  170. * the orgId to set
  171. */
  172. public void setOrgId(Long orgId) {
  173. this.orgId = orgId;
  174. }
  175.  
  176. /**
  177. * @return the orgId
  178. */
  179. public Long getOrgId() {
  180. return orgId;
  181. }
  182.  
  183. /**
  184. * @param officeTel
  185. * the officeTel to set
  186. */
  187. public void setOfficeTel(String officeTel) {
  188. this.officeTel = officeTel;
  189. }
  190.  
  191. /**
  192. * @return the officeTel
  193. */
  194. public String getOfficeTel() {
  195. return officeTel;
  196. }
  197.  
  198. /**
  199. * @param mobileTel
  200. * the mobileTel to set
  201. */
  202. public void setMobileTel(String mobileTel) {
  203. this.mobileTel = mobileTel;
  204. }
  205.  
  206. /**
  207. * @return the mobileTel
  208. */
  209. public String getMobileTel() {
  210. return mobileTel;
  211. }
  212.  
  213. /**
  214. * @param id
  215. * the id to set
  216. */
  217. public void setId(Long id) {
  218. this.id = id;
  219. }
  220.  
  221. /**
  222. * @return the id
  223. */
  224. public Long getId() {
  225. return id;
  226. }
  227.  
  228. public Date getLastUpdatedDate() {
  229. return lastUpdatedDate;
  230. }
  231.  
  232. public void setLastUpdatedDate(Date lastUpdatedDate) {
  233. this.lastUpdatedDate = lastUpdatedDate;
  234. }
  235.  
  236. }

组织对象

  1. package model;
  2.  
  3. import java.io.Serializable;
  4. import java.util.Date;
  5.  
  6. /**
  7. * 组织对象
  8. *
  9. *
  10. * @author Administrator
  11. * @version $Id$
  12. */
  13. public class JmsOrganize extends BaseModel implements Serializable{
  14. private static final long serialVersionUID = 1L;
  15. private Long id;
  16. private String orgName; //中文名
  17. private String orgFullName;
  18. private String orgEngName;//英文名
  19. private Long orgTypeNo;
  20. private String orgLevel;
  21. private Long parentOrgId;
  22. private String orgCode;
  23. private String orgDesc;
  24. private String isbranch;
  25. private Date lastUpdatedDate;
  26.  
  27. // Constructors
  28.  
  29. /** default constructor */
  30. public JmsOrganize() {
  31. }
  32.  
  33. /** default constructor */
  34. public JmsOrganize(Long id, String orgName) {
  35. this.setId(id);
  36. this.orgName = orgName;
  37.  
  38. }
  39.  
  40. public JmsOrganize(Long id, Long parendId) {
  41. this.setId(id);
  42. this.parentOrgId = parendId;
  43.  
  44. }
  45.  
  46. /** minimal constructor */
  47. public JmsOrganize(String orgName) {
  48. this.orgName = orgName;
  49. }
  50.  
  51. public String getOrgName() {
  52. return this.orgName;
  53. }
  54.  
  55. public void setOrgName(String orgName) {
  56. this.orgName = orgName;
  57. }
  58.  
  59. public String getOrgFullName() {
  60. return this.orgFullName;
  61. }
  62.  
  63. public void setOrgFullName(String orgFullName) {
  64. this.orgFullName = orgFullName;
  65. }
  66.  
  67. public Long getOrgTypeNo() {
  68. return this.orgTypeNo;
  69. }
  70.  
  71. public void setOrgTypeNo(Long orgTypeNo) {
  72. this.orgTypeNo = orgTypeNo;
  73. }
  74.  
  75. public String getOrgLevel() {
  76. return this.orgLevel;
  77. }
  78.  
  79. public void setOrgLevel(String orgLevel) {
  80. this.orgLevel = orgLevel;
  81. }
  82.  
  83. public String getOrgDesc() {
  84. return this.orgDesc;
  85. }
  86.  
  87. public void setOrgDesc(String orgDesc) {
  88. this.orgDesc = orgDesc;
  89. }
  90.  
  91. public String getIsbranch() {
  92. return this.isbranch;
  93. }
  94.  
  95. public void setIsbranch(String isbranch) {
  96. this.isbranch = isbranch;
  97. }
  98.  
  99. /**
  100. * @param parentOrgId the parentOrgId to set
  101. */
  102. public void setParentOrgId(Long parentOrgId) {
  103. this.parentOrgId = parentOrgId;
  104. }
  105.  
  106. /**
  107. * @return the parentOrgId
  108. */
  109. public Long getParentOrgId() {
  110. return parentOrgId;
  111. }
  112.  
  113. /**
  114. * @param orgCode the orgCode to set
  115. */
  116. public void setOrgCode(String orgCode) {
  117. this.orgCode = orgCode;
  118. }
  119.  
  120. /**
  121. * @return the orgCode
  122. */
  123. public String getOrgCode() {
  124. return orgCode;
  125. }
  126.  
  127. /**
  128. * @param orgEngName the orgEngName to set
  129. */
  130. public void setOrgEngName(String orgEngName) {
  131. this.orgEngName = orgEngName;
  132. }
  133.  
  134. /**
  135. * @return the orgEngName
  136. */
  137. public String getOrgEngName() {
  138. return orgEngName;
  139. }
  140.  
  141. /**
  142. * @param id the id to set
  143. */
  144. public void setId(Long id) {
  145. this.id = id;
  146. }
  147.  
  148. /**
  149. * @return the id
  150. */
  151. public Long getId() {
  152. return id;
  153. }
  154.  
  155. public Date getLastUpdatedDate() {
  156. return lastUpdatedDate;
  157. }
  158.  
  159. public void setLastUpdatedDate(Date lastUpdatedDate) {
  160. this.lastUpdatedDate = lastUpdatedDate;
  161. }
  162. }

由于发送的是对象,所以提供一个转换器,Convertor,该类要继承Spring的MessageConvertor

  1. package com.wc82.util;
  2.  
  3. import java.text.DateFormat;
  4.  
  5. import javax.jms.JMSException;
  6. import javax.jms.Message;
  7. import javax.jms.ObjectMessage;
  8. import javax.jms.Session;
  9.  
  10. import model.JmsFaUser;
  11. import model.JmsOrganize;
  12.  
  13. import org.apache.log4j.Logger;
  14. import org.springframework.jms.support.converter.MessageConversionException;
  15. import org.springframework.jms.support.converter.MessageConverter;
  16.  
  17. public class FaJmsConverter implements MessageConverter {
  18.  
  19. private static final Logger logger =Logger.getLogger(FaJmsConverter.class);
  20.  
  21. public Message toMessage(Object obj, Session session)
  22. throws JMSException, MessageConversionException {
  23. ObjectMessage objMsg=session.createObjectMessage();
  24. if(obj instanceof JmsFaUser){
  25. JmsFaUser user = (JmsFaUser)obj;
  26. logger.info("The user message's userId is " + user.getId());
  27. objMsg.setStringProperty("dataFlag", "FaUser");
  28. objMsg.setStringProperty("userName", user.getUserName());
  29. objMsg.setLongProperty("userId", user.getId());
  30. objMsg.setStringProperty("officeEmail", user.getOfficeEmail());
  31. objMsg.setStringProperty("selfEmail", user.getSelfEmail());
  32. if(user.getOfficeTel() != null){
  33. objMsg.setStringProperty("officeTel", user.getOfficeTel());
  34. }else{
  35. objMsg.setLongProperty("officeTel", new Long(0));
  36. }
  37. if(user.getMobileTel() != null){
  38. objMsg.setStringProperty("mobileTel", user.getMobileTel());
  39. }else{
  40. objMsg.setLongProperty("mobileTel", new Long(0));
  41. }
  42. if(user.getLastUpdatedDate() != null){
  43. objMsg.setStringProperty("lastUpdatedDate", DateFormat.getDateTimeInstance().format(user.getLastUpdatedDate()));
  44. }
  45.  
  46. }else if(obj instanceof JmsOrganize){
  47. JmsOrganize org = (JmsOrganize)obj;
  48. logger.info("The org message's userId is " + org.getId());
  49. objMsg.setStringProperty("dataFlag", "Organize");
  50. objMsg.setLongProperty("orgId", org.getId());
  51. objMsg.setStringProperty("orgName", org.getOrgName());
  52. if(org.getLastUpdatedDate() != null){
  53. objMsg.setStringProperty("lastUpdatedDate", DateFormat.getDateTimeInstance().format(org.getLastUpdatedDate()));
  54. }
  55. }
  56. return objMsg;
  57. }
  58.  
  59. public Object fromMessage(Message message) throws JMSException,
  60. MessageConversionException {
  61. logger.info("from message");
  62. ObjectMessage objMessage = (ObjectMessage)message;
  63. String dataFlag = objMessage.getStringProperty("dataFlag");
  64. if("FaUser".equals(dataFlag)){
  65. JmsFaUser user = new JmsFaUser();
  66. user.setId(objMessage.getLongProperty("userId"));
  67. user.setUserName(objMessage.getStringProperty("userName"));
  68. user.setOfficeEmail(objMessage.getStringProperty("officeEmail"));
  69. user.setSelfEmail(objMessage.getStringProperty("selfEmail"));
  70. user.setOfficeTel(objMessage.getStringProperty("officeTel"));
  71. user.setMobileTel(objMessage.getStringProperty("mobileTel"));
  72. String lastDate = objMessage.getStringProperty("lastUpdatedDate");
  73. try {
  74. if(lastDate != null){
  75. user.setLastUpdatedDate(DateFormat.getDateTimeInstance().parse(lastDate));
  76. }
  77. } catch (Exception e) {
  78. e.printStackTrace();
  79. }
  80. return user;
  81. }else if("Organize".equals(dataFlag)){
  82. Long orgId = objMessage.getLongProperty("orgId");
  83. String orgName = objMessage.getStringProperty("orgName");
  84. JmsOrganize organize = new JmsOrganize(orgId, orgName);
  85. String lastDate = objMessage.getStringProperty("lastUpdatedDate");
  86. try {
  87. organize.setLastUpdatedDate(DateFormat.getDateTimeInstance().parse(lastDate));
  88. } catch (Exception e) {
  89. e.printStackTrace();
  90. }
  91. return organize;
  92. }
  93. return null;
  94. }
  95.  
  96. }

3、发送

Sprng为我们提供了JMSTemplate,基于这个发送消息,我们先来看看Spring配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:jms="http://www.springframework.org/schema/jms"
  6. xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
  7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
  9. <!-- 外部属性文件的定义 -->
  10. <bean id="propertyConfigurer"
  11. class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  12. <property name="locations">
  13. <list>
  14. <value>classpath:sender.properties</value>
  15. </list>
  16. </property>
  17. </bean>
  18.  
  19. <!-- 配置connectionFactory -->
  20. <bean id="jmsSenderFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
  21. destroy-method="stop">
  22. <property name="connectionFactory">
  23. <bean class="org.apache.activemq.ActiveMQConnectionFactory">
  24. <property name="brokerURL" value="${jms.sendBrokerURL}">
  25. </property>
  26. <property name="useAsyncSend" value="true"></property>
  27. <property name="userName" value="admin"></property>
  28. <property name="password" value="admin"></property>
  29. </bean>
  30. </property>
  31. <property name="maxConnections" value="100"></property>
  32. </bean>
  33.  
  34. <bean id="jmsConverter" class="com.wc82.util.FaJmsConverter" />
  35.  
  36. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  37. <property name="connectionFactory" ref="jmsSenderFactory"></property>
  38. <property name="defaultDestination" ref="destination" />
  39. <!-- 区别它采用的模式为false是p2p为true是订阅 -->
  40. <property name="pubSubDomain" value="true" />
  41. <property name="messageConverter" ref="jmsConverter"></property>
  42. </bean>
  43.  
  44. <!-- 发送消息的目的地(一个队列) -->
  45. <bean id="destination" class="org.apache.activemq.command.ActiveMQTopic">
  46. <!-- 设置消息队列的名字 -->
  47. <constructor-arg index="0" value="${jms.sendDestinationName}" />
  48. </bean>
  49.  
  50. <bean id="messageProducer" class="message.MessageProducer">
  51. <property name="jmsTemplate" ref="jmsTemplate"></property>
  52. </bean>
  53.  
  54. </beans>

根据上面的配置,只需要获得messageProducer这个Bean,便可以发送,下面我来看看MessageProducer这个类及其接口

  1. package message.face;
  2.  
  3. public interface IJMSMessageProducer {
  4. public abstract void converAndSendObjectMessage(Object obj);
  5. }

实现类

  1. package message;
  2.  
  3. import message.face.IJMSMessageProducer;
  4.  
  5. import org.apache.log4j.Logger;
  6. import org.springframework.jms.core.JmsTemplate;
  7.  
  8. public class MessageProducer implements IJMSMessageProducer {
  9.  
  10. private static final Logger logger =Logger.getLogger(MessageProducer.class);
  11.  
  12. private JmsTemplate jmsTemplate;
  13.  
  14. /**
  15. * @param jmsTemplate
  16. * the jmsTemplate to set
  17. */
  18. public void setJmsTemplate(JmsTemplate jmsTemplate) {
  19. this.jmsTemplate = jmsTemplate;
  20. }
  21.  
  22. /*
  23. * (non-Javadoc)
  24. *
  25. * @see
  26. * com.vispractice.faf.jms.IJMSMessageProducer#converAndSendObjectMessage
  27. * (java.lang.Object)
  28. *
  29. * @date 2012-10-25
  30. *
  31. * @user
  32. */
  33. public void converAndSendObjectMessage(Object obj) {
  34. jmsTemplate.convertAndSend(obj);
  35. logger.info("The message pub success, the Object is " + obj);
  36. }
  37.  
  38. }

发送测试

  1. package com.wc82.ActivemqTransData;
  2.  
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.util.Properties;
  7.  
  8. import message.face.IJMSMessageProducer;
  9. import model.JmsFaUser;
  10.  
  11. import org.springframework.context.ApplicationContext;
  12. import org.springframework.context.support.ClassPathXmlApplicationContext;
  13.  
  14. public class SendTest {
  15. public static void main(String[] args) {
  16.  
  17. Properties pro=new Properties();
  18. try {
  19. InputStream input=SendTest.class.getResourceAsStream("/sender.properties");
  20. pro.load(input);
  21. } catch (FileNotFoundException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. pro.setProperty("count", new Integer(0).toString());
  25. } catch (IOException e) {
  26. // TODO Auto-generated catch block
  27. e.printStackTrace();
  28. }
  29. Object obj=pro.get("jms.jmsSendConverterClass");
  30. ApplicationContext ac = new ClassPathXmlApplicationContext(
  31. "jms-sender.xml");
  32. IJMSMessageProducer messageProducer = (IJMSMessageProducer) ac.getBean("messageProducer");
  33. JmsFaUser user = new JmsFaUser();
  34. user.setUserName("ssss");
  35. user.setId(new Long(111));
  36. messageProducer.converAndSendObjectMessage(user);
  37. }
  38. }

那发送到神马位置呢?在发送消息的Spring配置文件里面,有一个jms.sendBrokerURL,这个值是在sender.properties文件中配置的,方便修改,我们来看一下关于发送消息时所以配置的参数信息

  1. jms.sendBrokerURL=tcp\://localhost\:61616
  2. jms.sendDestinationName=faJMS

第一个指地址,因为ActiveMQ部署的是我本机,所以使用localhost,端口号在部署的时候,就是默认的

第二个JMS的名称,这个可以自取

如果发送,可以通过localhost:8161的控制台,看到你所发送的消息,这个地址是ActiveMQ的Web控制台,接下为我们看看接收

4、接收

MQ给我提供一种方式,当接收到消息的时候,自动去执行我们业务代码,

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:jms="http://www.springframework.org/schema/jms"
  6. xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
  7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
  9. <description>jms receiver configuration</description>
  10.  
  11. <!-- 外部属性文件的定义 -->
  12. <bean id="propertyConfigurer"
  13. class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  14. <property name="locations">
  15. <list>
  16. <value>classpath:receiver.properties</value>
  17. </list>
  18. </property>
  19. </bean>
  20.  
  21. <!-- 配置connectionFactory -->
  22. <bean id="jmsReceiverFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
  23. destroy-method="stop">
  24. <property name="connectionFactory">
  25. <bean class="org.apache.activemq.ActiveMQConnectionFactory">
  26. <property name="brokerURL" value="${jms.receiveBrokerURL}" />
  27. <!-- <property name="userName" value="reader"></property> -->
  28. <!-- <property name="password" value="readeryxtech"></property> -->
  29. </bean>
  30. </property>
  31. <property name="maxConnections" value="100"></property>
  32. </bean>
  33.  
  34. <bean id="destination" class="org.apache.activemq.command.ActiveMQTopic">
  35. <!-- 设置消息队列的名字 -->
  36. <constructor-arg index="0" value="${jms.receiveDestinationName}" />
  37. </bean>
  38.  
  39. <bean id="jmsConverter" class="com.wc82.util.FaJmsConverter" />
  40.  
  41. <!--异步调用消息 -->
  42. <bean id="receive"
  43. class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  44. <property name="connectionFactory" ref="jmsReceiverFactory"></property>
  45. <property name="destination" ref="destination"></property>
  46. <property name="messageListener" ref="messageListener"></property>
  47. </bean>
  48.  
  49. <bean id="delegate" class="message.MessageConsumer"></bean>
  50.  
  51. <bean id="messageListener"
  52. class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
  53. <property name="delegate" ref="delegate"></property>
  54. <property name="defaultListenerMethod" value="onMessage"></property>
  55. <property name="messageConverter" ref="jmsConverter" />
  56. </bean>
  57.  
  58. </beans>

先看一下messageListener,这个监听,是自己写的,其中delegate是当你接收消息之后所执行的业务代码的bean,我这里将这个bean做成配置,方便修改,而defaultListenerMethod是指定执行的方法,这里设置定了,执行omMessage方法,也就是说类你可以指定,但是onMessage方法必须要有,而convertor也是可配的,与发送的convertor是一样的,这个转换器发送与接收都必须要使用

注意:这里为神马要将执行的类的bean做成可配呢?因为我在做这一块的工作时,我不知道是由那个bean,但是类中的方法我可设置,这样做的目地就是在消息的消费者不在去关心这个消息,而只需要写一个类,里面有onMessage方法,在这个方法里做自己的业务逻辑即可,将其关注点放到业务处理上,那肿么样来设计这个方法的名字呢,我们可以设计了一个接口,如果消费者想消费这个消息,就必须实现这上接口,下面我们来看看这个接口

  1. package message.face;
  2.  
  3. public interface FaJmsReceiveListener {
  4. public void onMessage(Object baseModel);
  5. }

这个接口中只有一个方法就是onMessage,而实现类则交由具体的消费者,因为消费可能在实现的时候可能引用别的bean,进而处理别的业务,例如入库,所以我们在做接收消息的配置上,只设计处理消息的bean的名字,不设置具体的class,只要消费者配置了这个bean的名字即可,当然这个名字也是可配的,配置在了init.propertis中,我们来看看这个接口的实现类

  1. package message;
  2.  
  3. import org.apache.log4j.Logger;
  4.  
  5. import message.face.FaJmsReceiveListener;
  6. import model.JmsFaUser;
  7. import model.JmsOrganize;
  8.  
  9. public class MessageConsumer implements FaJmsReceiveListener{
  10.  
  11. private static final Logger logger=Logger.getLogger(MessageConsumer.class);
  12.  
  13. public void onMessage(Object baseModel) {
  14. if(baseModel instanceof JmsFaUser){
  15. JmsFaUser user = (JmsFaUser)baseModel;
  16. logger.info(user.getId());
  17. }else if (baseModel instanceof JmsOrganize){
  18. JmsOrganize org = (JmsOrganize)baseModel;
  19. logger.info(org.getId());
  20. }
  21. }
  22.  
  23. }

上述的代码可以共用,当发送的类变更时,只需要编写Convertor,并在init.properties中配置上即可,而消息的消费者只需要实现该接口即可

测试类

  1. package com.wc82.ActivemqTransData;
  2.  
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. public class ReceiveTest {
  7. public static void main(String[] args) {
  8. ApplicationContext a2c = new ClassPathXmlApplicationContext("jms-receiver.xml");
  9. System.out.println("receiver");
  10. }
  11. }

接下来,看看接收的receiver.properties

  1. jms.receiveBrokerURL=tcp\://localhost\:61616
  2. jms.receiveDestinationName=faJMS
 

第一个、第二个、第三个参数不再详细述说,第四就是执行业务逻辑的bean的名字,这个参数可以设定死也可以设定灵活

上述只是初步的能发送和接收消息,后续是考虑安全、性能的问题。

注意测试时:要先打开消息接收程序,然后再打开消息发送程序。activemq是实时性的,不会将消息保存下来,发送消息的程序在发送消息时,如果接收程序没有启动,那么这个接收程序就接收不到这个消息。下一节,就是用来解决这个持久订阅的问题。

基于ActiveMQ的Topic的数据同步——初步实现的更多相关文章

  1. 基于ActiveMQ的Topic的数据同步——消费者持久化

    前面一章中介绍了activemq的初步实现:基于ActiveMQ的Topic的数据同步——初步实现 下面来解决持久化订阅的问题: (1)使用queue,即队列时,每个消息只有一个消费者,所以,持久化很 ...

  2. 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原

    一.背景 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数据可以 ...

  3. 基于MySQL Binlog的Elasticsearch数据同步实践

    一.为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数 ...

  4. linux下数据同步、回写机制分析

    一.前言在linux2.6.32之前,linux下数据同步是基于pdflush线程机制来实现的,在linux2.6.32以上的版本,内核彻底删掉了pdflush机制,改为了基于per-bdi线程来实现 ...

  5. 阿里Canal框架(数据同步中间件)初步实践

    最近在工作中需要处理一些大数据量同步的场景,正好运用到了canal这款数据库中间件,因此特意花了点时间来进行该中间件的的学习和总结. 背景介绍 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存 ...

  6. 基于canal的client-adapter数据同步必读指南

    本文将介绍canal项目中client-adapter的使用,以及落地生产中需要考虑的可靠性.高可用与监控报警.(基于canal 1.1.4版本) canal作为mysql的实时数据订阅组件,实现了对 ...

  7. 总结:基于Oracle Logminer数据同步

    第 1 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan LogMiner 配置使用手册 1 Logminer 简介 1.1 LogMin ...

  8. 基于datax的数据同步平台

    一.需求 由于公司各个部门对业务数据的需求,比如进行数据分析.报表展示等等,且公司没有相应的系统.数据仓库满足这些需求,最原始的办法就是把数据提取出来生成excel表发给各个部门,这个功能已经由脚本转 ...

  9. 基于TreeSoft实现异构数据同步

    一.为了解决数据同步汇聚,数据分发,数据转换,数据维护等需求,TreeSoft将复杂的网状的同步链路变成了星型数据链路.     TreeSoft作为中间传输载体负责连接各种数据源,为各种异构数据库之 ...

随机推荐

  1. php实现微信扫码自动登陆与注册功能

    本文实例讲述了php实现微信扫码自动登陆与注册功能.分享给大家供大家参考,具体如下: 微信开发已经是现在程序员必须要掌握的一项基本的技术了,其实做过微信开发的都知道微信接口非常的强大做起来也非常的简单 ...

  2. iOS耗电量测试方法及其数据收集

    常用的电量测试方法: 硬件测试(硬件要求比较高,成本比较大,这里介绍软件测试方法) 软件工具检测 几个典型的耗电场景如下: 定位,尤其是调用GPS定位 网络传输,尤其是非Wifi环境 cpu频率 内存 ...

  3. 解决:创建Android模拟器时提示“No system images installed for target”

    今天在Eclipse上创建安卓模拟器,但发现CPU/ABI一项显示为“No system images installed for target”: 在网上搜索答案,在叶超Luka的博客中找到了答案, ...

  4. poj3694 边-双连通分量+lca

    题意:先给了一张无向图,然后依次加边,每次求桥的数量 题解:先用一次tarjan,我们可以标记桥的位置和记录桥的数量同时记录fa数组,然后更新边的时候我们可以用lca,因为在tarjan缩点之后得到了 ...

  5. spring boot 基础篇 -- 集成接口测试Swagger

    一.在pom.xml加入Swagger jar包引入 <dependency> <groupId>io.springfox</groupId> <artifa ...

  6. SpringBoot邮件发送功能

    快速入门 在Spring Boot的工程中的pom.xml中引入spring-boot-starter-mail依赖: <dependency> <groupId>org.sp ...

  7. A*B problem(FFT)

    #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #inclu ...

  8. java 连接oracle数据库

    package shujuku; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepared ...

  9. VS软件版本号定义、规则和相关的Visual Studio插件

    http://blog.csdn.net/cnhk1225/article/details/37500593 软件版本号主要标识了软件的版本,通过其可以了解软件.类库文件的当前版本,使得软件版本控制有 ...

  10. [转]移动端HTML5<video>视频播放优化实践

    遇到的挑战 移动端HTML5使用原生<video>标签播放视频,要做到两个基本原则,速度快和体验佳,先来分析一下这两个问题. 下载速度 以一个8s短视频为例,wifi环境下提供的高清视频达 ...