Spring JMS 中的 JmsTemplate 回调是啥?

Posted

技术标签:

【中文标题】Spring JMS 中的 JmsTemplate 回调是啥?【英文标题】:What is a JmsTemplate callback in Spring JMS?Spring JMS 中的 JmsTemplate 回调是什么? 【发布时间】:2015-06-10 03:23:33 【问题描述】:

这是我第一次使用 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 callback 但可能这个断言是不正确的。

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

【问题讨论】:

【参考方案1】:

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

在 JMS 中连接将从工厂获得

=> 从创建连接会话开始,一个seesion 是一个工作单元,它还提供事务

=> 从会话中,您可以通过以下方式创建不同类型的 JMS 消息,例如 TextMessage、ObjectMessage、MapMessage、BytesMessage 和 StreamMessage session.createTextMessage("你好队列世界"); session.createObjectMessage(someSerializedObject) 等等

=> 同一个 session 还负责创建 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.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 接口可让您在消息转换后访问,但在发送之前。

【讨论】:

【参考方案2】:

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

【讨论】:

嗯,它对我来说仍然是一些模糊的东西。那么这些回调是什么(除了SessionCallback),所以我会尝试搜索一些示例 你可以直接在Session上执行操作——阅读JMS规范。和 Javadocs 了解更多信息。

以上是关于Spring JMS 中的 JmsTemplate 回调是啥?的主要内容,如果未能解决你的问题,请参考以下文章

JMS与Sping

JMS与数据库事务

如何使用 Spring JMS 发布 JMS 主题?

Spring整合activeMQ消息队列

Spring - 动态创建 JMSTemplates

为啥 jmsTemplate 总是为空?使用 spring 和 Apache ActiveMQ [重复]