什么是Spring JMS中的JmsTemplate回调?

时间:2015-04-05 16:04:45

标签: java spring spring-mvc jms spring-jms

这是我第一次使用 Spring JMS (以及一般的JMS),我对 JmsTemplate 回调的概念有些怀疑。

我知道 JmsTemplate 是一个从Spring提供的类:

  • 减少样板代码。
  • 透明地管理资源。
  • 将已检查的异常转换为运行时等效项。
  • 提供便利方法和回调。

它用于消息生成和同步消息接收。它简化了JMS的使用,因为它在发送或同步接收消息时处理资源的创建和释放。

阅读Spring官方文档(此处:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html),我发现:

  

使用JmsTemplate的代码只需要实现回调   接口为他们提供明确定义的高级合同。该   MessageCreator回调接口在给定Session的情况下创建消息   由JmsTemplate中的调用代码提供。

这对我来说并不清楚。这些回调究竟是什么?

一开始我认为回调是从 JmsTemplate 提供的方法,但在这里阅读它似乎更像我必须实现的接口。它是如何工作的?

我也找到了这个例子:

通过JMS发送POJO(使用JmsTemplate):

public class JmsOrderManager implements OrderManager {
    @Autowired JmsTemplate jmsTemplate;
    @Autowired Destination orderQueue;

    public void placeOrder(Order order) {
        String stringMessage = "New order " + order.getNumber();
        jmsTemplate.convertAndSend("messageQueue", stringMessage );
        // use destination resolver and message converter
        jmsTemplate.convertAndSend(orderQueue, order); // use message converter
        jmsTemplate.convertAndSend(order); // use converter and default destination
    }
}

我认为 convertAndSend()方法是JmsTemplate 回调,但可能这个断言不正确。

你能解释一下JmsTemplate回调到底是什么吗?

2 个答案:

答案 0 :(得分:8)

Spring模板类的常见设计原则是提供 执行常用操作的辅助方法 而对于更复杂的用法,委托了本质 处理任务到用户实现的回调接口。

在JMS Connection中将从工厂获得

=>从该连接创建会话,视图是一个工作单元,它还提供事务

=>从会话中,您可以通过以下方式创建不同类型的JMS消息,如TextMessage,ObjectMessage,MapMessage,BytesMessage和StreamMessage session.createTextMessage(“hello queue world”); session.createObjectMessage(someSerializedObject)等等

=>同一会话还负责创建MessageProducer session.createProducer(destination)和MessageConsumer session.createConsumer(destination)的实例

您有以下convertAndSend可能性(重载方法):

        jmsTemplate.convertAndSend(message)
        jmsTemplate.convertAndSend(destination, message)
        jmsTemplate.convertAndSend(message, postProcessor)
        jmsTemplate.convertAndSend(destinationName, message)
        jmsTemplate.convertAndSend(destination, message, postProcessor)
        jmsTemplate.convertAndSend(destinationName, message, postProcessor)

发生了什么事? 回调的基本用法如第3和第5签名是您可以在将对象转换为JMS消息后更改消息 通过配置的MessageConverter。 你看到一个实际目的地要由DestinationResolver在6日的情况下解决,你没有传递它,它将从JNDI解析,如果它在那里注册。

这是什么意思?

jmsTemplate.send(this.queue, new MessageCreator() {
public  Message createMessage(Session session) throws JMSException {
        return  session.createTextMessage("hello queue world");
    }
});

在这个示例中,您将看到JMS模板的send()方法,您正在提供匿名实现(回调),其中该方法允许您访问会话对象并从该会话 您创建了自定义的session.createTextMessage(“hello queue world”)消息。

与convertAndSend相同(您可以访问要修改的后处理器)

public void ConvertSend() {
Map map = new HashMap();
map.put("Name", "Vimal");
map.put("Age", new Integer(45));
jmsTemplate.convertAndSend("jmsQueue", map, new MessagePostProcessor() {
    public Message postProcessMessage(Message message) throws JMSException {
        message.setIntProperty("ID", 9999);
        message.setJMSCorrelationID("123-99999");
        return message;
       }
   });
}

已创建消息对象,但您正在修改它(除了名称和年龄之外,还添加了两个属性)。 MessagePostProcessor接口允许您在转换消息之后但在发送之前访问消息。

换句话说!消息属性,标题和正文的设置无法封装在转换器类(SimpleMessageConverter)中,但MessagePostProcessor接口允许您在转换后对消息进行访问,但在发送之前。

答案 1 :(得分:4)

它允许您对JMS实体进行低级访问(例如,使用Session访问SessionCallback中的execute()),同时在操作完成时仍然可靠地释放资源。