`
myrev
  • 浏览: 164028 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

Spring + ActiveMQ 实现

阅读更多
站内消息模块在多数OA系统中是不可缺少的一部分。

     一般来说,是消息是存储在数据库中的,但最关键的是消息发送及接收处理的环节。如果直接用一个Action方法处理,然后调用Service来存储消息,那样也是可以的,问题是等待的时间较长,而且耗费服务器的资源。这种方法相当于同步处理。

     因此,采用另一外种方法:异步处理。说到这里,想到twitter的系统,虽然它是采用Ruby On Rails + Scala等实现的,但思想是相同的!客户端发送一个信息(任务)过来,后台把任务加入队列,队列是由若干个守护进程处理的!这样不仅能实时处理客户的其 它请求,也能充分利用系统的资源。

     那么下面开始简要写一下Spring中的JMS配置。注意,运行时要启动ActiveMQ的服务器~~,,当然你也可以自己配置嵌入服务器的ActiveMQ.。

     添加一个applicationContext-jms.xml文件。
 <!-- ActiveMQ 连接 -->
    <bean id="connectionFactory"
            class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616" />
        <property name="useAsyncSend" value="true"/>
    </bean>
    <bean id="destination" 
            class="org.apache.activemq.command.ActiveMQQueue">
            <constructor-arg index="0" value="myqueue"></constructor-arg>
    </bean>
    
    <bean id="jmsTemplate"
            class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory"></property>
        <property name="defaultDestination" ref="destination"></property>
        <property name="messageConverter" ref="innerMessageConverter"></property>
    </bean>
    
    <bean id="innerMessageConverter" class="jmu.xmpg.service.jms.InnerMessageConverter"></bean>
    
    <bean id="messageService" class="jmu.xmpg.service.jms.MessageServiceImpl">
        <!-- <property name="jmsTemplate" ref="jmsTemplate"></property> -->
    </bean>
    
    <bean id="messageListener" class="jmu.xmpg.service.jms.MessageMDB"></bean>
     
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" lazy-init="false">
        <property name="connectionFactory" ref="connectionFactory"></property>
        <property name="destination" ref="destination"></property>
        <property name="messageListener" ref="messageListener"></property>
        <property name="concurrentConsumers" value="5"></property>
        <!--0:CACHE_NONE,1:CACHE_CONNECTION,2:CACHE_SESSION,3:CACHE_CONSUMER,4:CACHE_AUTO-->
        <property name="cacheLevel" value="0"/>
    </bean>



下面简单说明一下各个bean:
connectionFactory:用来连接ActiveMQ的连接Bean
destination:用来作为信息发送的目的地队列。
jmsTemplate: Spring封装的JMS发送接收模板。
messageConverter: 对接收和发送的消息进行转换,写一次,就能省下每次的自己手动转换,:D
messageService:消息Service,用来调用发送消息。
messageListener: 消息驱动Bean,在EJB中称为MDB,用来监听队列中的消息,异步接收处理消息
jmsContainer:消息监听容器,当消息到达时,将消息转给messageListener,而且可以设置多个消费者。想起操作系统中的 消费者-生产者的问题了,,哈。
      这里,列出主要使用的代码:
转换器InnerMessageConverter.java
public class InnerMessageConverter implements MessageConverter {
public InnerMessageConverter(){}

@Override
public Object fromMessage(Message message) throws JMSException,
MessageConversionException {
  if(!(message instanceof MapMessage)){
    throw new MessageConversionException("Message isn't a MapMessage");
  }
  MapMessage msg = (MapMessage)message;
  MessageDescription messageDescription = new MessageDescription();
  messageDescription.setContent(msg.getString("content"));
  messageDescription.setCreateDate(new Date(msg.getLong("createDate")));
  messageDescription.setLevel(msg.getShort("level"));
  messageDescription.setToUserIds(msg.getString("toUserIds"));
  messageDescription.setFromUserName(msg.getString("fromUserName"));
  return messageDescription;
}

@Override
public Message toMessage(Object object, Session session) throws JMSException,
  MessageConversionException {
  if(!(object instanceof MessageDescription)){
    throw new MessageConversionException("Object isn't a MessageDescription");
  }
  MessageDescription messageDescription = (MessageDescription)object;
  MapMessage message = session.createMapMessage();
  message.setString("content", messageDescription.getContent());
  message.setLong("createDate", messageDescription.getCreateDate().getTime());
  message.setShort("level", messageDescription.getLevel());
  message.setString("toUserIds", messageDescription.getToUserIds());
  message.setString("fromUserName", messageDescription.getFromUserName());
  return message;
 }
}


消息Service:MessageServiceImpl.java
MessageService接口为自定义,主要有recevie和send方法,这里就不列出。
注意看 Send方法,简单吧:D,有加入转换器,代码就是少~~

package jmu.xmpg.service.jms;
import jmu.xmpg.dao.jms.InnerMessageDao;
import jmu.xmpg.entity.jms.InnerMessage;
import jmu.xmpg.entity.jms.MessageDescription;
import jmu.xmpg.entity.user.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;
/**
*
* @date : Jun 26, 2009 5:16:44 PM
* Filename :MessageServiceImpl.java
* Author: SloanWu
*/
@Transactional(readOnly=true)
public class MessageServiceImpl implements MessageService{
@Autowired
private JmsTemplate jmsTemplate;

@Autowired
private InnerMessageDao innerMessageDao;

@Override
public Page<InnerMessage> recevie(User user, Page<InnerMessage> page){
  page = innerMessageDao.getAll(page);
  return page;
}

@Override
public void send(final MessageDescription mesinfo){
    jmsTemplate.convertAndSend(mesinfo);
  }
}



下面一个是最主要的代码:MessageMDB.java
主要方法为onMessage:用来转换消息,processMessage,用来处理转换后的消息,可以用Spring的消息代理来简化这个MDB,并且可以不用实现MessageListener接口,纯POJO!

package jmu.xmpg.service.jms;
import java.util.Date;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import jmu.xmpg.dao.jms.InnerMessageDao;
import jmu.xmpg.dao.jms.MessageDescriptionDao;
import jmu.xmpg.dao.user.UserDao;
import jmu.xmpg.entity.jms.InnerMessage;
import jmu.xmpg.entity.jms.MessageDescription;
import jmu.xmpg.entity.user.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.transaction.annotation.Transactional;
import freemarker.template.utility.StringUtil;
/**
*
* @date : Jun 26, 2009 5:44:26 PM
* Filename :MessageMDB.java
* Author: SloanWu
*/
//默认将类中的所有函数纳入事务管理.
@Transactional
public class MessageMDB implements MessageListener{

@Autowired
private InnerMessageDao innerMessageDao;

@Autowired
private MessageDescriptionDao messageDescriptionDao;

@Autowired
private UserDao userDao;

@Override
public void onMessage(Message message) {
try {
    if(!(message instanceof MapMessage)){
      throw new MessageConversionException("Message isn't a MapMessage");
    }
    MapMessage msg = (MapMessage)message;
    MessageDescription messageDescription = new MessageDescription();
    messageDescription.setContent(msg.getString("content"));
    messageDescription.setCreateDate(new Date(msg.getLong("createDate")));
    messageDescription.setLevel(msg.getShort("level"));
    messageDescription.setToUserIds(msg.getString("toUserIds"));
    messageDescription.setFromUserName(msg.getString("fromUserName"));
    processMessage(messageDescription);
  } catch (Exception e) {
    System.out.println("JMS Exception:"+e.toString());
  }
}

private void processMessage(MessageDescription mesDescription){
  testShow(mesDescription);
  User fromUser = userDao.loadByLoginName(mesDescription.getFromUserName());
  mesDescription.setFromUser(fromUser);
  messageDescriptionDao.save(mesDescription);
  String[] ids = StringUtil.split(mesDescription.getToUserIds(), ',');
  for (int i = 0; i < ids.length; i++) {
    User toUser = new User();
    toUser.setId(Long.valueOf(ids[i]));
    InnerMessage inner = new InnerMessage();
    inner.setMessageDescription(mesDescription);
    inner.setReadable(false);
    inner.setToUser(toUser);
    innerMessageDao.save(inner);
  }
}
  private void testShow(MessageDescription mesDescription) {
    System.out.println("--收到消息:"+mesDescription.getFromUserName());
    System.out.println("-----时间:"+mesDescription.getCreateDate());
    System.out.println("--消息等级:"+mesDescription.getLevel());
    System.out.println("--消息内容:"+mesDescription.getContent());
    System.out.println("--接收用户:"+mesDescription.getToUserIds());
  }
}


分享到:
评论
2 楼 guojiew 2015-07-07  
只是剪切了一部分代码出来,看的真是脑袋大。
1 楼 Qudong_0129 2013-03-13  
哥们能把代码贴全不? 或者上传个附件..只看这些看的我云里雾里的...谢谢了!

相关推荐

    JMS之Spring +activeMQ实现消息队列

    总结起来,"JMS之Spring + ActiveMQ实现消息队列"涉及到的关键知识点包括:Spring框架的JMS支持、ActiveMQ的使用、ConnectionFactory的配置、JmsTemplate和MessageListener的实现,以及消息队列在解决系统解耦和异步...

    Spring+ActiveMQ实现,基于Maven

    在企业级应用开发中,Spring框架与ActiveMQ的结合使用是一种常见的消息中间件解决方案,用于实现应用程序间的异步通信和解耦。本项目基于Maven构建,提供了对Topic的实现,同时也支持轻松切换到Queue模式。 **...

    Spring+ActiveMQ整合实例代码工程

    在Java开发中,Spring框架是极为重要的应用基础,而ActiveMQ作为Apache出品的一款开源消息中间件,常被用于实现应用间的异步通信和解耦。本实例代码工程"Spring+ActiveMQ整合实例代码工程"正是结合两者,展示了如何...

    Spring+JMS+ActiveMQ+Tomcat实现消息服务的demo

    基于Spring+JMS+ActiveMQ+Tomcat,我使用的版本情况如下所示:Spring 3.2.0,ActiveMQ 5.4.3,Tomcat 6.0.43。本例通过详细的说明和注释,实现消息服务的基本功能:发送与接收。Spring对JMS提供了很好的支持,可以...

    spring+activemq

    在IT行业中,Spring框架与...总结,Spring与ActiveMQ的集成为开发者提供了强大而便捷的工具来实现异步通信,提高了系统的可扩展性和解耦性。通过理解并熟练运用这些技术,开发者能够构建出高效、稳定的分布式应用。

    springboot-nettysocketio +netty+activeMq在线客服系统

    springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot +netty+activeMq在线客服系统springboot...

    jms Spring+ActiveMQ 5.4.2

    总结起来,"jms Spring+ActiveMQ 5.4.2"是一个关于如何利用Spring框架和ActiveMQ实现高效、可靠的JMS通信的教程或示例。通过学习这个主题,开发者可以掌握如何在Java环境中构建健壮的、分布式的消息驱动系统。

    springMvc+spring+activeMq+mybaits

    在IT行业中,构建高效、可扩展的Web应用是至关重要的,而"springMvc+spring+activeMq+mybaits"这个项目组合提供了一个强大的框架基础。本文将深入探讨这四个关键技术及其相互间的协同工作。 首先,Spring MVC是...

    SpringBoot+ActiveMq+MQTT实现消息的发送和接收

    在本文中,我们将深入探讨如何使用SpringBoot、ActiveMQ和MQTT来实现消息的发送与接收。这是一个典型的分布式系统中的消息通信场景,其中SpringBoot作为应用程序框架,ActiveMQ作为消息中间件,而MQTT(Message ...

    Spring + ActiveMq + maven demo

    **Spring + ActiveMQ + Maven 整合示例详解** 在当今的软件开发中,Spring框架因其强大的功能和灵活性,已经成为Java企业级应用的首选。同时,消息中间件ActiveMQ作为Apache出品的一款开源JMS(Java Message ...

    spring + activemq 消息sample

    本示例主要关注如何将Spring框架与ActiveMQ整合,以便实现异步通信和解耦系统组件。下面我们将深入探讨相关知识点。 首先,**Spring框架** 是一个广泛使用的Java企业级应用开发框架,它提供了依赖注入(Dependency ...

    Spring+ActiveMQ的整合

    Spring框架作为Java领域最流行的开发框架之一,提供了强大的依赖注入和面向切面编程功能,而ActiveMQ则是Apache软件基金会的一个开源消息中间件,实现了Java Message Service (JMS) 规范,用于在应用程序之间高效、...

    activemq学习(2) spring+activemq

    标题 "activemq学习(2) spring+activemq" 暗示了这篇内容将探讨如何在Spring框架中集成ActiveMQ,一个流行的开源消息代理和消息中间件。ActiveMQ允许应用程序之间通过消息传递进行通信,而Spring则是一个广泛使用...

    Spring+JMS+ActiveMQ+Tomcat jar下载

    Spring、JMS、ActiveMQ和Tomcat是Java开发中常用的技术组件,它们分别扮演着不同的角色,构建出高效的企业级消息通信系统。本教程将详细阐述这些技术的使用及其相互结合的方式。 首先,Spring是一个开源的Java应用...

    Spring+JMS+ActiveMQ+Tomcat实现消息服务_服务器应用

    ### Spring+JMS+ActiveMQ+Tomcat 实现消息服务 #### 一、技术栈介绍 在本案例中,我们采用的技术栈为Spring 2.5、ActiveMQ 5.4.0 和 Tomcat 6.0.30。这些技术的结合能够有效地构建一个可靠的消息传递系统。 - **...

    基于Spring+JMS+ActiveMQ+Tomcat整合

    基于Spring+JMS+ActiveMQ+Tomcat,做一个Spring4.1.0和ActiveMQ5.11.1整合实例,实现了Point-To-Point的异步队列消息和PUB/SUB(发布/订阅)模型,简单实例,不包含任何业务。

    Spring+ActiveMQ消息队列+前台接收消息

    在本教程中,我们将探讨如何整合Spring框架与ActiveMQ消息队列,实现前后台的消息传递。这有助于提升系统的可扩展性和响应速度,降低不同组件之间的耦合度。 首先,Spring框架是Java企业级应用开发的事实标准,它...

    spring+jms+activemq

    本文将深入探讨如何使用Spring框架与ActiveMQ结合实现基于JMS的消息传递系统。 首先,理解JMS的基本概念至关重要。JMS定义了生产者(Producer)、消费者(Consumer)和消息队列(Queue)或主题(Topic)等核心组件...

Global site tag (gtag.js) - Google Analytics