首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Spring Boot监听动态目的地?

如何使用Spring Boot监听动态目的地?
EN

Stack Overflow用户
提问于 2019-05-21 03:24:19
回答 1查看 2K关注 0票数 3

我们有一个使用Spring Boot及其JMS工具的应用程序。在运行时,我们有不同的生产者在线跳转,并告诉我们的应用程序要侦听的主题或队列的名称。现在,我们有:

代码语言:javascript
复制
@JmsListener(destination = "helloworld.q")
public void receive(String message) {
  LOGGER.info("received message='{}'", message);
}

当我们向helloworld.q主题发送消息时,它会起作用。问题是,在运行之前我们不知道主题的名称是什么,而JmsListener似乎想要一个常量表达式。

消息生成器将连接到我们的ActiveMQ实例,并广播一条消息,告诉我们需要开始侦听它们的主题,例如"Wasabi“、"WhitePaper”、"SatelliteMajor“、"BigBoosters”等。

我已经阅读了Spring文档,该文档解释了如何在运行时(某种程度上)侦听主题/队列:

代码语言:javascript
复制
@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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-21 04:33:35

您可以使用属性占位符作为目标名称

代码语言:javascript
复制
@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时设置命令行属性

代码语言:javascript
复制
-Dfoo.bar=baz

编辑

您可以使侦听器bean成为原型并调整环境属性。

代码语言:javascript
复制
@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);
        }

    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56226984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档