Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
505 views
in Technique[技术] by (71.8m points)

java - create queue/exchange/binding/listener at run time in spring boot rabbitmq

I am using spring-boot with rabbitmq. 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can't easily do it with @RabbitListener (you can, but you have to create a new child application context for each).

You can use a RabbitAdmin to dynamically create the queues and bindings and create a message listener container for each new queue.

EDIT

This is one way to do it with @RabbitListener and child contexts; when using Spring Boot, the ListenerConfig class must not be in the same package (or child package) as the boot application itself.

@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);
    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...