10

I want to be able to set the @JMSlistener destination from an application.properties

my code looks like this

@Service
public class ListenerService {
    private Logger log = Logger.getLogger(ListenerService.class);

    @Autowired
    QueueProperties queueProperties;


    public ListenerService(QueueProperties queueProperties) {
        this.queueProperties = queueProperties;

    }

    @JmsListener(destination = queueProperties.getQueueName() )
    public void listenQueue(String requestJSON) throws JMSException {
        log.info("Received " + requestJSON);

    }
}

but when building I get

Error:(25, 60) java: element value must be a constant expression
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
JaChNo
  • 1,493
  • 9
  • 28
  • 56

2 Answers2

16

You can't reference a field within the current bean, but you can reference another bean in the application context using a SpEL expression...

@SpringBootApplication
public class So49368515Application {

    public static void main(String[] args) {
        SpringApplication.run(So49368515Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(JmsTemplate template, Foo foo) {
        return args -> template.convertAndSend(foo.getDestination(), "test");
    }

    @JmsListener(destination = "#{@foo.destination}")
    public void listen(Message in) {
        System.out.println(in);
    }

    @Bean
    public Foo foo() {
        return new Foo();
    }

    public class Foo {

        public String getDestination() {
            return "foo";
        }
    }

}

You can also use property placeholders ${...}.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Gary any reason why this has not been implemented yet? It would be really helpful if reference to the current bean is available in spel? – Indraneel Bende Mar 19 '18 at 17:52
  • 2
    It's not a question of not implemented **yet** - there is no way for an Annotation to reference the bean it is used in; the value has to be static since it's stored in the Class file. – Gary Russell Mar 19 '18 at 17:55
  • I dont understand this code. it seems to return "Foo", not the value of foo.destination – john k Feb 14 '23 at 21:59
  • It is not clear what you mean, in SpEL, `@foo.destination` means call the `getDestination()` method on the bean named `foo`. If you can't figure it out, ask a new question showing your code and config. – Gary Russell Feb 14 '23 at 22:02
6

Using property placeholder is much easier.

@JmsListener(destination = "${mq.queue}")
public void onMessage(Message data) {

}
Chris
  • 61
  • 1
  • 1