主题解析
目录
在生成或消费消息时,需要一个目标主题(destination topic)。框架会按照以下顺序查找以确定主题(在第一次找到时停止):
-
用户指定
-
消息类型默认
-
全局默认
当一个主题通过默认机制之一被发现时,无需在 produce 或 consume API 上指定主题。
当主题未找到时,API 会相应地抛出异常。
1. 用户指定
传递给所使用的 API 的主题具有最高优先级(例如 PulsarTemplate.send("my-topic", myMessage)
或 @PulsarListener(topics = "my-topic"
)。
2. 消息类型默认
当没有传递主题到 API 时,系统会查找为正在生成或消费的消息类型配置的消息类型到主题的映射。
可以通过 spring.pulsar.defaults.type-mappings
属性来配置映射。以下示例使用 application.yml
来配置在消费或生产 Foo
或 Bar
消息时使用的默认主题:
spring:
pulsar:
defaults:
type-mappings:
- message-type: com.acme.Foo
topic-name: foo-topic
- message-type: com.acme.Bar
topic-name: bar-topic
message-type
是消息类的完全限定名。
如果消息(或 Publisher
输入的第一个消息)为 null
,框架将无法从中确定主题。如果您的应用程序可能会发送 null
消息,则应使用另一种方法来指定主题。
2.1. 通过注解指定
当没有传递主题到 API 且没有配置自定义主题映射时,系统会在生产或消费的消息类上查找 @PulsarMessage
注解。默认主题可以通过注解上的 topic
属性指定。
以下示例配置了在生产或消费类型为 Foo
的消息时使用的默认主题:
@PulsarMessage(topic = "foo-topic")
record Foo(String value) {
}
@PulsarMessage
注解支持属性占位符和 SpEL 表达式,例如:
@PulsarMessage(topic = "${app.topics.foo}")
record Foo(String value) {
}
@PulsarMessage(topic = "#{someBean.getTopic()}")
record Bar(String value) {
}
2.2. 自定义主题解析器
首选的方法是通过上述属性添加映射。然而,如果需要更多的控制,你可以通过提供自己的实现来替换默认的解析器,例如:
@Bean
public MyTopicResolver topicResolver() {
return new MyTopicResolver();
}
3. 生产者全局默认
在生成消息时,最后参考的位置是系统范围内的生产者默认主题。当使用命令式 API 时,通过 spring.pulsar.producer.topic-name
属性进行配置;当使用响应式 API 时,通过 spring.pulsar.reactive.sender.topic-name
属性进行配置。
4. 消费者全局默认值
最终消费时查询的位置是系统范围内的消费者默认主题。当使用命令式 API 时,通过 spring.pulsar.consumer.topics
或 spring.pulsar.consumer.topics-pattern
属性进行配置;当使用响应式 API 时,则通过 spring.pulsar.reactive.consumer.topics
或 spring.pulsar.reactive.consumer.topics-pattern
属性进行配置。