12

I'm writing a Kafka consumer. I need to pass the environment variable topic name to @KafkaListener(topics = ...). This is what I have tried so far:

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.kafka.annotation.KafkaListener; 
 import org.springframework.stereotype.Service;

 @Service
 public class KafkaConsumer {

     @Autowired
     private EnvProperties envProperties;

     private final String topic = envProperties.getTopic();

     @KafkaListener(topics = "#{'${envProperties.getTopic()}'}", groupId = "group_id")
     public void consume(String message) {
        logger.info("Consuming messages " +envProperties.getTopic());
     }
}

I'm getting an error at the line topics = "#{'${envProperties.getTopic()}'}", the application fails to start.

How to set this topic name dynamically from the environment variable?

Vladimir Vagaytsev
  • 2,871
  • 9
  • 33
  • 36
CodeCool
  • 193
  • 2
  • 12

3 Answers3

4

Normally, you can't reference fields or properties from the bean in which the SpEL is declared. However, @KafkaListener has special syntax to support it.

See the documentation.

Starting with version 2.1.2, the SpEL expressions support a special token __listener which is a pseudo bean name which represents the current bean instance within which this annotation exists.

So, if you add public EnvProperties getEnvProperties() to the class then something like

#{__listener.envProperties.topic}

should work.

Olivier Boissé
  • 15,834
  • 6
  • 38
  • 56
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
3

In KafkaConsumer class, you need to make below changes :

@Autowired
public EnvProperties envProperties;

@KafkaListener(topics = "#{kafkaConsumer.envProperties.getTopic()}"

It worked for me.

Himi-Hash
  • 31
  • 3
0

If you are looking to set topic as an environmental variable, you can pass the topic below

@KafkaListener(topics = "#{systemEnvironment['TOPIC']}")

Then you can set topic as below,

export TOPIC=mytopic
Pubudu
  • 51
  • 5