我们有一个使用 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 使所有这些东西都被自动调用,而我们不知道在哪里以及如何为该方法提供端点需要侦听的主题/队列的名称。另外,消息监听器似乎永远不会被调用,但这是一个单独的问题;我相信如果我们至少可以发送自定义主题或队列以供其收听,我们就可以解决这个问题。
我们正在使用 Spring 2。x.
您可以使用属性占位符作为目标名称
@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
EDIT
您可以将侦听器 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);
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)