Spring JMS中的JmsTemplate回调是什么?

9
这是我第一次使用Spring JMS(也是JMS的初次接触),我对JmsTemplate回调的概念有一些疑问。 我知道JmsTemplate是Spring提供的一个类,它可以: - 减少样板代码 - 透明地管理资源 - 将已检查的异常转换为运行时异常 - 提供方便的方法和回调函数
它用于消息生产和同步消息接收。由于在发送或同步接收消息时处理资源的创建和释放,因此简化了JMS的使用。
阅读Spring官方文档(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html),我发现:
“只使用JmsTemplate的代码仅需要实现回调接口,为它们提供一个明确定义的高级契约。MessageCreator回调接口根据JmsTemplate中调用代码提供的Session创建消息。”
对我来说,这并不清楚。这些回调到底是什么?

一开始,我以为回调是由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个回答

11

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

JMS中,连接将从工厂获取。

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

=> 从会话中,以以下方式创建不同类型的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和6个签名,是在将对象转换为JMS消息后,通过配置的MessageConverter更改消息内容。 在第6个签名中,您会看到实际的目标需要由DestinationResolver解析,如果您没有传递它,它将从JNDI中解析,如果已在那里注册。

这是什么意思?

jmsTemplate.send(this.queue, new MessageCreator() {
public  Message createMessage(Session session) throws JMSException {
        return  session.createTextMessage("hello queue world");
    }
});
在这个例子中,你使用JMS模板的send()方法提供了一个匿名实现(回调函数),该方法让你访问Session对象,并从该会话中创建自定义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接口使您能够在消息转换后但在发送之前访问该消息。


5

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


嗯,对我来说仍然有些不清楚。那么除了SessionCallback之外,这些回调是什么,所以我会尝试搜索一些示例。 - AndreaNobili
2
您可以直接在“Session”上执行操作,有关更多信息,请阅读JMS规范和Javadocs。 - Gary Russell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接