AMQ学习笔记 - 11. Spring-JmsTemplate之执行

概述


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

执行


1.关于回调接口

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

2.执行的方法

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

 

P.S.第6行的doSend是一个protected的方法,简单说下:它需要session和destination来创建producer;需要messageCreator来创建message,然后producer发送message。我们的send并没有Session资源,所以在send和doSend之间,隔了一层SessionCallback,来获取Session资源。



来自为知笔记(Wiz)



posted on 2016-04-26 11:29  一尾金鱼  阅读(1773)  评论(0编辑  收藏  举报