继 Spring 6.1 中引入的 JdbcClientRestClient 之后,Spring 7.0 再次带来了新的客户端 API:JmsClient。笔者认为这个全新的客户端为 JMS 消息操作提供了更加现代化和流式的 API 体验。

概述

cJXj1V JMS(Java Message Service)是 Java 平台中用于在分布式应用程序之间发送消息的 API 规范。它提供了一种标准化的方式来创建、发送、接收和读取消息,支持点对点(队列)和发布/订阅(主题)两种消息传递模式。 JmsClient 是一个流式的 JMS 客户端,提供了针对 JMS 目标的常见发送和接收操作。它可以处理 Spring 的通用 Message 或直接处理有效载荷值,并且与 spring-messaging 模块保持一致,抛出 MessagingException 而不是 JMS 特定的 JmsException 实际上,JmsClientJmsMessagingTemplate 的一个现代化替代方案,同样委托给 Spring 的 JmsTemplate 来执行实际操作。

核心特性

1. 流式 API 设计

JmsClient 采用了与 JdbcClientRestClient 相似的流式 API 设计模式,使代码更加简洁和易读:
// 发送消息到队列
client.destination("myQueue")
    .withTimeToLive(1000)
    .send("myPayload");

// 从队列接收消息
Optional<String> payload = client.destination("myQueue")
    .withReceiveTimeout(1000)
    .receive(String.class);

2. 多种创建方式

JmsClient 提供了多种静态工厂方法来创建实例:
// 基于 ConnectionFactory 创建
JmsClient client = JmsClient.create(connectionFactory);

// 基于 ConnectionFactory 和 MessageConverter 创建
JmsClient client = JmsClient.create(connectionFactory, messageConverter);

// 基于现有的 JmsTemplate 创建
JmsClient client = JmsClient.create(jmsTemplate);

// 基于 JmsTemplate 和 MessageConverter 创建
JmsClient client = JmsClient.create(jmsTemplate, messageConverter);

3. 灵活的目标配置

支持多种方式指定 JMS 目标:
// 使用目标名称
client.destination("myQueue")

// 使用 Destination 对象
client.destination(jmsDestination)

主要操作类型

1. 发送操作 (Send)

JmsClient 提供了多种发送消息的方式:
// 发送简单有效载荷
client.destination("myQueue").send("Hello World");

// 发送有效载荷和头部信息
Map<String, Object> headers = Map.of("priority", 5);
client.destination("myQueue").send("Hello World", headers);

// 发送完整的 Message 对象
Message<?> message = MessageBuilder.withPayload("Hello World")
    .setHeader("customHeader", "value")
    .build();
client.destination("myQueue").send(message);

2. 接收操作 (Receive)

支持多种接收消息的方式:
// 接收并转换为指定类型
Optional<String> payload = client.destination("myQueue")
    .receive(String.class);

// 接收完整的 Message 对象
Optional<Message<?>> message = client.destination("myQueue")
    .receive();

// 使用消息选择器接收
Optional<String> payload = client.destination("myQueue")
    .receive("priority > 5", String.class);

3. 请求-响应操作 (Send and Receive)

支持同步的请求-响应模式:
// 发送请求并接收响应
Optional<String> response = client.destination("requestQueue")
    .sendAndReceive("request payload", String.class);

// 带头部信息的请求-响应
Map<String, Object> headers = Map.of("requestId", "123");
Optional<String> response = client.destination("requestQueue")
    .sendAndReceive("request payload", headers, String.class);

// 发送 Message 对象并接收响应
Message<?> requestMessage = MessageBuilder.withPayload("request").build();
Optional<Message<?>> responseMessage = client.destination("requestQueue")
    .sendAndReceive(requestMessage);

QoS 设置

JmsClient 提供了丰富的服务质量 (QoS) 配置选项:

1. 消息生存时间

client.destination("myQueue")
    .withTimeToLive(30000)  // 30秒
    .send("time-sensitive message");

2. 消息优先级

client.destination("myQueue")
    .withPriority(9)  // 高优先级
    .send("urgent message");

3. 持久化设置

client.destination("myQueue")
    .withDeliveryPersistent(true)  // 持久化消息
    .send("important message");

4. 延迟发送

client.destination("myQueue")
    .withDeliveryDelay(5000)  // 延迟5秒发送
    .send("delayed message");

5. 接收超时

Optional<String> payload = client.destination("myQueue")
    .withReceiveTimeout(10000)  // 10秒超时
    .receive(String.class);

与传统方式的对比

传统的 JmsTemplate 方式:

@Service
public class TraditionalJmsService {
    
    @Autowired
    private JmsTemplate jmsTemplate;
    
    public void sendMessage(String message) {
        jmsTemplate.setTimeToLive(30000);
        jmsTemplate.setPriority(5);
        jmsTemplate.convertAndSend("myQueue", message);
    }
    
    public String receiveMessage() {
        jmsTemplate.setReceiveTimeout(5000);
        return (String) jmsTemplate.receiveAndConvert("myQueue");
    }
}

使用 JmsClient 的现代方式:

@Service
public class ModernJmsService {
    
    private final JmsClient jmsClient;
    
    public void sendMessage(String message) {
        jmsClient.destination("myQueue")
            .withTimeToLive(30000)
            .withPriority(5)
            .send(message);
    }
    
    public Optional<String> receiveMessage() {
        return jmsClient.destination("myQueue")
            .withReceiveTimeout(5000)
            .receive(String.class);
    }
}

总结

JmsClient 是 Spring 7.0 中一个重要的新特性,它为 JMS 消息操作提供了更加现代化和用户友好的 API。通过流式设计、类型安全和一致的异常处理,JmsClient 使得 JMS 编程变得更加简单和直观。 对于已经熟悉 JdbcClientRestClient 的开发者来说,JmsClient 提供了相似的 API 体验,降低了学习成本。同时,它也为新项目提供了一个更好的起点,让开发者能够以更现代的方式处理 JMS 消息。 随着 Spring 7.0 的发布,JmsClient 将成为 JMS 消息处理的推荐方式,特别是在需要简洁、类型安全和易于测试的场景中。