java Spring JMS 中的 JmsTemplate 回调是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29459256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:19:18  来源:igfitidea点击:

What is a JmsTemplate callback in Spring JMS?

javaspringspring-mvcjmsspring-jms

提问by Java Surfer

this is my first time with Spring JMS(and with JMS in general) and I have some doubts related the concept of the JmsTemplatecallback.

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

I know that the JmsTemplateis a class provided from Spring to:

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

  • Reduces boilerplate code.
  • Manages resources transparently.
  • Converts checked exceptions to runtime equivalents.
  • Provides convenience methods and callbacks.
  • 减少样板代码。
  • 透明地管理资源。
  • 将检查异常转换为运行时等效项。
  • 提供方便的方法和回调。

and that it is used for message production and synchronous message reception. It simplifies the use of JMS since it handles the creation and release of resources when sending or synchronously receiving messages.

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

Reading the Spring official documentation (here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html) I found:

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

Code that uses the JmsTemplate only needs to implement callback interfaces giving them a clearly defined high level contract. The MessageCreator callback interface creates a message given a Session provided by the calling code in JmsTemplate.

使用 JmsTemplate 的代码只需要实现回调接口,为它们提供明确定义的高级合同。MessageCreator 回调接口根据 JmsTemplate 中的调用代码提供的 Session 创建一条消息。

This is not clear for me. What exactly are these callback?

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

At the beginning I thought that a callback are a method provided from the JmsTemplatebut reading here it seems something more similar to an interface that I have to implement. How it works?

一开始我认为回调是JmsTemplate提供的方法,但在这里阅读它似乎更类似于我必须实现的接口。怎么运行的?

I also found this example:

我还发现了这个例子:

SENDING A POJO THROUGHT JMS (using the 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
    }
}

I thought that the convertAndSend()method is a JmsTemplate callbackbut probably this assertion is not correct.

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

Can you explain me what exactly is a JmsTemplate callback?

你能解释一下 JmsTemplate 回调究竟是什么吗?

回答by vimal krishna

The design principle common to Spring template classes is to provide helper methods to perform common operationsand for more sophisticated usage, delegate the essence of the processing task to user implemented callback interfaces.

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

In JMS Connection will be obtained from a factory

在 JMS 连接中将从工厂获得

=> From that connection session is created, a seesion is a unit of work, it also provides transaction

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

=> from session you create different types of JMS Message like TextMessage, ObjectMessage, MapMessage, BytesMessage and StreamMessage in following ways session.createTextMessage("hello queue world"); session.createObjectMessage(someSerializedObject) and so on

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

=> The same session is also responsible for creating instance of MessageProducer session.createProducer(destination) and MessageConsumer session.createConsumer(destination)

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

You have following convertAndSend possibilities (Overloaded methods):

您有以下 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)

What is happening?The basic use of callback like 3rd 5th and 6th signature is you can change the message after being converting the object to a JMS message through a configured MessageConverter. You are seeing an actual destination to be resolved by a DestinationResolver in case of 6th, you are not passing it, it will be resolved from JNDI, if it is registered there.

怎么了?回调的基本用途如 3rd 5th 和 6th 签名是您可以在通过配置的 MessageConverter 将对象转换为 JMS 消息后更改消息。在第 6 种情况下,您会看到由 DestinationResolver 解析的实际目的地,您没有传递它,它将从 JNDI 解析,如果它在那里注册。

What does it mean?

这是什么意思?

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

Here in this example you are seeing with send() method of JMS template you are providing anonymous implemetation(callback) where the method gives you access to to Session Object and from that session you created customized session.createTextMessage("hello queue world") message.

在此示例中,您使用 JMS 模板的 send() 方法看到您提供匿名实现(回调),该方法使您可以访问会话对象,并从该会话创建自定义 session.createTextMessage("hello queue world")信息。

Same way in convertAndSend(you can get access to postprocessors to modify)

在 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;
       }
   });
}

Message Object was created but you are modifying it(adding two more properties, in addition to name and age). The MessagePostProcessor interface gives you access to the message after it has been converted, but before it is sent.

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

In other words!setting of message properties, headers and body can't be encapsulated inside a converter class(SimpleMessageConverter), but the MessagePostProcessor Interface gives you access to the message after it has been converted, but before sent.

换句话说!消息属性、标题和正文的设置不能封装在转换器类 (SimpleMessageConverter) 中,但是 MessagePostProcessor 接口使您可以在消息转换后但在发送之前访问消息。

回答by Gary Russell

It allows you low level access to JMS entities (e.g. to the Sessionin the SessionCallbackusing execute()), while still reliably releasing resources when the operation is complete.

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