Topic Resolution

A destination topic is needed when producing or consuming messages. The framework looks in the following ordered locations to determine a topic (stopping at the first find):spring-doc.cn

When a topic is found via one of the default mechanisms, there is no need to specify the topic on the produce or consume API.spring-doc.cn

When a topic is not found, the API will throw an exception accordingly.spring-doc.cn

1. User specified

A topic passed into the API being used has the highest precedence (eg. PulsarTemplate.send("my-topic", myMessage) or @PulsarListener(topics = "my-topic").spring-doc.cn

2. Message type default

When no topic is passed into the API, the system looks for a message type to topic mapping configured for the type of the message being produced or consumed.spring-doc.cn

Mappings can be configured with the spring.pulsar.defaults.type-mappings property. The following example uses application.yml to configure default topics to use when consuming or producing Foo or Bar messages:spring-doc.cn

spring:
  pulsar:
    defaults:
      type-mappings:
        - message-type: com.acme.Foo
          topic-name: foo-topic
        - message-type: com.acme.Bar
          topic-name: bar-topic
The message-type is the fully-qualified name of the message class.
If the message (or the first message of a Publisher input) is null, the framework won’t be able to determine the topic from it. Another method shall be used to specify the topic if your application is likely to send null messages.

2.1. Specified via annotation

When no topic is passed into the API and there are no custom topic mappings configured, the system looks for a @PulsarMessage annotation on the class of the message being produced or consumed. The default topic can be specified via the topic attribute on the annotation.spring-doc.cn

The following example configures the default topic to use when producing or consuming messages of type Foo:spring-doc.cn

@PulsarMessage(topic = "foo-topic")
record Foo(String value) {
}

Property placeholders and SpEL expressions are supported in the @PulsarMessage annotation, for example:spring-doc.cn

@PulsarMessage(topic = "${app.topics.foo}")
record Foo(String value) {
}

@PulsarMessage(topic = "#{someBean.getTopic()}")
record Bar(String value) {
}

2.2. Custom topic resolver

The preferred method of adding mappings is via the property mentioned above. However, if more control is needed you can replace the default resolver by proving your own implementation, for example:spring-doc.cn

@Bean
public MyTopicResolver topicResolver() {
	return new MyTopicResolver();
}

3. Producer global default

The final location consulted (when producing) is the system-wide producer default topic. It is configured via the spring.pulsar.producer.topic-name property when using the imperative API and the spring.pulsar.reactive.sender.topic-name property when using the reactive API.spring-doc.cn

4. Consumer global default

The final location consulted (when consuming) is the system-wide consumer default topic. It is configured via the spring.pulsar.consumer.topics or spring.pulsar.consumer.topics-pattern property when using the imperative API and one of the spring.pulsar.reactive.consumer.topics or spring.pulsar.reactive.consumer.topics-pattern property when using the reactive API.spring-doc.cn