简体   繁体   English

在Spring Boot Rabbitmq中的运行时创建队列/交换/绑定/侦听器

[英]create queue/exchange/binding/listener at run time in spring boot rabbitmq

I am using spring-boot with rabbitmq. 我在rabbitmq中使用spring-boot。 I have created some queues/exchanges/bindings/listeners which are fixed. 我创建了一些固定的队列/交换/绑定/侦听器。

listener is created as following: 侦听器的创建如下:

@RabbitListener
public void foo(String msg) {...}

Now i want to create queue at run time for every user whenever he login along with exchange/binding/listener and destroy these whenever user logout. 现在,我想在运行时为每个用户在与交换/绑定/侦听器一起登录时创建队列,并在用户注销时销毁这些队列。 How can i do this in spring-boot. 我如何在春季启动中做到这一点。

You can't easily do it with @RabbitListener (you can, but you have to create a new child application context for each). 您无法使用@RabbitListener轻松完成此@RabbitListener (可以,但是必须为每个应用程序创建一个新的子应用程序上下文)。

You can use a RabbitAdmin to dynamically create the queues and bindings and create a message listener container for each new queue. 您可以使用RabbitAdmin动态创建队列和绑定,并为每个新队列创建消息侦听器容器。

EDIT 编辑

This is one way to do it with @RabbitListener and child contexts; 这是使用@RabbitListener和子上下文的一种方法。 when using Spring Boot, the ListenerConfig class must not be in the same package (or child package) as the boot application itself. 使用Spring Boot时, ListenerConfig类不得与引导应用程序本身位于同一软件包(或子软件包)中。

@SpringBootApplication
public class So48617898Application {

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

    private final Map<String, ConfigurableApplicationContext> children = new HashMap<>();

    @Bean
    public ApplicationRunner runner(RabbitTemplate template, ApplicationContext context) {
        return args -> {
            Scanner scanner = new Scanner(System.in);
            String line = null;
            while (true) {
                System.out.println("Enter a new queue");
                line = scanner.next();
                if ("quit".equals(line)) {
                    break;
                }
                children.put(line, addNewListener(line, context));
                template.convertAndSend(line, "test to " + line);
            }
            scanner.close();
            for (ConfigurableApplicationContext ctx : this.children.values()) {
                ctx.stop();
            }
        };
    }

    private ConfigurableApplicationContext addNewListener(String queue, ApplicationContext context) {
        AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
        child.setParent(context);
        ConfigurableEnvironment environment = child.getEnvironment();
        Properties properties = new Properties();
        properties.setProperty("queue.name", queue);
        PropertiesPropertySource pps = new PropertiesPropertySource("props", properties);
        environment.getPropertySources().addLast(pps);
        child.register(ListenerConfig.class);
        child.refresh();
        return child;
    }

}

and

@Configuration
@EnableRabbit
public class ListenerConfig {

    @RabbitListener(queues = "${queue.name}")
    public void listen(String in, @Header(AmqpHeaders.CONSUMER_QUEUE) String queue) {
        System.out.println("Received " + in + " from queue " + queue);
    }

    @Bean
    public Queue queue(@Value("${queue.name}") String name) {
        return new Queue(name);
    }

    @Bean
    public RabbitAdmin admin(ConnectionFactory cf) {
        return new RabbitAdmin(cf);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM