我们有一个使用Spring Boot及其JMS工具的应用程序。在运行时,我们有不同的生产者在线跳转,并告诉我们的应用程序要侦听的主题或队列的名称。现在,我们有:
@JmsListener(destination = "helloworld.q")
public void receive(String message) {
LOGGER.info("received message='{}'", message);
}
当我们向helloworld.q
主题发送消息时,它会起作用。问题是,在运行之前我们不知道主题的名称是什么,而JmsListener
似乎想要一个常量表达式。
消息生成器将连接到我们的ActiveMQ实例,并广播一条消息,告诉我们需要开始侦听它们的主题,例如"Wasabi“、"WhitePaper”、"SatelliteMajor“、"BigBoosters”等。
我已经阅读了Spring文档,该文档解释了如何在运行时(某种程度上)侦听主题/队列:
@Configuration
@EnableJms
public class ReceiverConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setId("myJmsEndpoint");
endpoint.setDestination("anotherQueue");
endpoint.setMessageListener(message -> {
// processing
});
registrar.registerEndpoint(endpoint);
}
// other methods...
}
我已经把它作为测试放到了我们的接收器配置中,当我们发送消息时,它确实会被调用。问题是,Spring让所有这些东西被自动调用,我们不知道在哪里以及如何给这个方法提供端点需要侦听的主题/队列的名称。此外,消息侦听器似乎永远不会被调用,但这是一个单独的问题;我相信,如果我们至少可以发送定制的主题或队列让它侦听,我们就可以解决这个问题。
我们使用的是Spring2.x。
发布于 2019-05-21 04:33:35
您可以使用属性占位符作为目标名称
@SpringBootApplication
public class So56226984Application {
public static void main(String[] args) {
SpringApplication.run(So56226984Application.class, args);
}
@JmsListener(destination = "${foo.bar}")
public void listen(String in) {
System.out.println(in);
}
@Bean
public ApplicationRunner runner(JmsTemplate template) {
return args -> template.convertAndSend("baz", "qux");
}
}
然后设置属性,例如在Spring Boot应用程序的application.yml中,或者在启动JVM时设置命令行属性
-Dfoo.bar=baz
编辑
您可以使侦听器bean成为原型并调整环境属性。
@SpringBootApplication
public class So56226984Application {
public static void main(String[] args) {
SpringApplication.run(So56226984Application.class, args).close();
}
@Bean
public ApplicationRunner runner(JmsTemplate template, JmsListenerEndpointRegistry registry,
ConfigurableApplicationContext context) {
return args -> {
Scanner scanner = new Scanner(System.in);
String queue = scanner.nextLine();
Properties props = new Properties();
context.getEnvironment().getPropertySources().addLast(new PropertiesPropertySource("queues", props));
while (!"quit".equals(queue)) {
System.out.println("Adding " + queue);
props.put("queue.name", queue);
context.getBean("listener", Listener.class);
template.convertAndSend(queue, "qux sent to " + queue);
System.out.println("There are now " + registry.getListenerContainers().size() + " containers");
queue = scanner.nextLine();
}
scanner.close();
};
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Listener listener() {
return new Listener();
}
public static class Listener {
@JmsListener(destination = "${queue.name}")
public void listen(String in) {
System.out.println(in);
}
}
}
https://stackoverflow.com/questions/56226984
复制相似问题