ActiveMQ——5.Spring-JmsTemplate之浏览与执行

浏览

概述


浏览只是针对Queue的概念,Topic没有浏览。浏览是指获取消息而消息依然保持在broker中,而消息的接收会把消息从broker中移除。
浏览可以用来实现对Queue中消息的监控。

JMS API


浏览的概念来源于JMS,所以有必要先把JmsTemplate放一放。先看一下下面的API:
Interface javax.jms.Session
  • QueueBrowser createBrowser(Queue queue)
    创建指定Queue的Browser对象。
  • QueueBrowser createBrowser(Queue queue, java.lang.String messageSelector)
    创建指定Queue的Browser对象,添加选择器筛选消息。
Interface javax.jms.QueueBrowser
  • java.util.Enumeration getEnumeration()
    获取Message的枚举,每一个元素都是Message实例
  • void close()
    通知broker可以回收分配给当前browser的资源
根据上面的API,我们应该可以这样使用:
复制代码
1 QueueBrowser browser = session.createBrowser(queue);
2 Enumeration msgEnum = browser.getEnumeration();
3 browser.close();
4 
5 while (msgEnum.hasMoreElements()) {
6     Message msg = msgEnum.nextElement();
7 } 
复制代码
P.S.只是推论,没有验证。

JmsTemplate的API


JmsTemplate提供了2组*3,共计6个浏览的方法。
  1. 基本的浏览
  2. 带有选择器的浏览
 
鉴于我们对这种分组的习惯、消息选择器的概念都已经驾轻就熟,所以这里不再分开介绍。我们一鼓作气,解决掉吧:
Class org.springframework.jms.core.JmsTemplate
  • public T browse(BrowserCallback action)
    从默认的Queue中浏览消息,要求设置了默认的Destination,且类型为Queue。action是一个回调对象,它负责浏览消息,并返回浏览的结果。
  • public T browse(Queue queue, BrowserCallback action)
    从指定的Queue中浏览消息。
  • public T browse(String queueName, BrowserCallback action)
    从指定name的Queue中浏览消息。
  • public T browseSelected(String messageSelector, BrowserCallback action)
    从默认的Queue中浏览消息,添加了消息选择器。
  • public T browseSelected(Queue queue, String messageSelector, BrowserCallback action)
    从指定的Queue中浏览消息,添加了消息选择器。
  • public T browseSelected(String queueName, String messageSelector, BrowserCallback action)
    从指定name的Queue中浏览消息,添加了消息选择器。
Interface org.springframework.jms.core.BrowserCallback
  • T doInJms(Session session, QueueBrowser browser)
    浏览队列中的消息,并返回浏览的结果。这是一个回调方法,Spring会为我们提供QueueBrowser对象,我们可以据此获取消息,并自由的转换。最后以我们希望的类型返回。
 
让我们先看下BrowserCallback定义的回调方法。我们在客户端和broker建立连接的整个过程中,截取这样的一段:
我们已经使用Session创建了QueueBrowser的实例,然后我们像前文的demo中那样浏览消息。我们决定对消息再做一下转换,比如如果能确定每一个消息的内容都是一个字符串,我们可以最终转换成java.util.List类型的结果。
这个片段是我们浏览Queue的整个片段,这个片段也是BrowserCallback唯一关心的问题,我们定义了这个片段的具体实现,然后交给JmsTemplate,由它在合适的时候,按照我们定义的方式浏览并返回消息。
 
下面给个demo:
List contList = jt.browse(DESTINATION_NAME,
        new BrowserCallback>() {
        
            public List doInJms(Session session,
                    QueueBrowser browser) throws JMSException {
                    
                MessageConverter converter = new SimpleMessageConverter();
                List messContentList = new ArrayList();
                
                @SuppressWarnings("unchecked")
                Enumeration messageEnum = browser
                        .getEnumeration();
                while (messageEnum.hasMoreElements()) {
                    Message msg = messageEnum.nextElement();
                    String text = (String) converter.fromMessage(msg);
                    messContentList.add(text);
                }
                return messContentList;
            }
        });
        
for (String text : contList) {
    System.out.println(text);
}


执行

概述


前面我们分别介绍了发送、接收和浏览,这三个的实现都依赖于将要介绍的执行。
执行算是一个相对比较底层的方法系列,一般情况下,我们不需要直接面向将要介绍的方法。

执行


1.关于回调接口

在讲执行之前,我们先回忆一下之前将的发送、接收和浏览。JmsTemplate接管了整个过程,但是考虑到我们可能在某个特殊的阶段做一些特殊的处理,所以又在敏感的点给我们自主行为的机会——以回调接口的方式。我们实现回调,JmsTemplate在到了那个点时,调用我们的回调。让我们看一下我们接触到的回调接口:
发送
  • MessageCreator
    创建消息,使用基本的发送方法时可用
  • MessagePostProcessor
    消息后处理,使用转换、后处理再发送的方法时可用
浏览
  • BrowserCallback
    浏览消息
接下来,我们来接触两个新的回调接口。
 
Interface org.springframework.jms.core.ProducerCallback
  • T doInJms(Session session, MessageProducer producer)
    面向发送的回调方法,实现消息的创建、发送,并自由返回想要的类型。
Interface org.springframework.jms.core.SessionCallback
  • T doInJms(Session session)
    回调方法,接收Session资源,并自由通信和返回。
现在我们已经接触了5个回调接口,我们可以把MessageCreator、MessagePostProcessor归为一类,因为它们的名字表达了它们的作用,即它们是有非常强的目的性的,如果你实际上用它们来做其他的事情,恐怕有违设计者的初衷。我们把BrowserCallback、ProducerCallback、SessionCallback归为一类,因为它们的名字强调了它们需要的资源,或者说是被调用的时机。比如BrowserCallback需要QueueBrowser资源,在创建了QueueBrowser之后调用。其中,BrowserCallback和ProducerCallback所需要的资源的本身,也有非常强的目的:你要QueueBrowser就是为了浏览,你要MessageProducer就是为了发送。而SessionCallback需要的是Session资源,JMS中所有的通信类型都需要Session,所以我们也不能确定它的目的——即,它给了我们自由发挥的空间。
 
Session位于编程模型的唯一主干道,而且在末端,如下面这样:
ActiveMQ——5.Spring-JmsTemplate之浏览与执行_第1张图片

Spring一贯的思想就是:帮我们做尽量多的事,又给我们留一定的空间做其他的事。

2.执行的方法

使用 ProducerCallback和 SessionCallback,JmsTemplate定义了5个方法。


Class org.springframework.jms.core.JmsTemplate
  • public T execute(ProducerCallback action)
    基于默认的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(Destination destination, ProducerCallback action)
    基于指定的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(String destinationName, ProducerCallback action)
    基于指定的name所对应的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(SessionCallback action)
    创建Session,执行回调方法并提供Session作为参数
  • public T execute(SessionCallback action, boolean startConnection)
    创建Session,执行回调方法并提供Session作为参数。startConnection表示是否在调用javax.jms.Connection#start()方法。如果你是写消息到broker,那么使用false;如果你是从broker获取消息(接收或者浏览),那么使用true。
 
最后我们给一个demo,这个demo来自JmsTemplate# send(Destination destination, MessageCreator messageCreator):
@Override
public void send(final Destination destination, final MessageCreator messageCreator) throws JmsException {
    execute(new SessionCallback() {
        @Override
        public Object doInJms(Session session) throws JMSException {
            doSend(session, destination, messageCreator);
            return null;
        }
    }, false);
} 
   
Class org.springframework.jms.core.JmsTemplate
  • public T execute(ProducerCallback action)
    基于默认的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(Destination destination, ProducerCallback action)
    基于指定的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(String destinationName, ProducerCallback action)
    基于指定的name所对应的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(SessionCallback action)
    创建Session,执行回调方法并提供Session作为参数
  • public T execute(SessionCallback action, boolean startConnection)
    创建Session,执行回调方法并提供Session作为参数。startConnection表示是否在调用javax.jms.Connection#start()方法。如果你是写消息到broker,那么使用false;如果你是从broker获取消息(接收或者浏览),那么使用true。
 
最后我们给一个demo,这个demo来自JmsTemplate# send(Destination destination, MessageCreator messageCreator):

P.S.第6行的doSend是一个protected的方法,简单说下:它需要session和destination来创建producer;需要messageCreator来创建message,然后producer发送message。我们的send并没有Session资源,所以在send和doSend之间,隔了一层SessionCallback,来获取Session资源。
Class org.springframework.jms.core.JmsTemplate
  • public T execute(ProducerCallback action)
    基于默认的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(Destination destination, ProducerCallback action)
    基于指定的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(String destinationName, ProducerCallback action)
    基于指定的name所对应的Destination创建MessageProducer,并在该发送的时候调用回调接口,如何发送由回调接口的实现决定。
  • public T execute(SessionCallback action)
    创建Session,执行回调方法并提供Session作为参数
  • public T execute(SessionCallback action, boolean startConnection)
    创建Session,执行回调方法并提供Session作为参数。startConnection表示是否在调用javax.jms.Connection#start()方法。如果你是写消息到broker,那么使用false;如果你是从broker获取消息(接收或者浏览),那么使用true。
 
最后我们给一个demo,这个demo来自JmsTemplate# send(Destination destination, MessageCreator messageCreator):

你可能感兴趣的:(MQ(消息队列))