繁体   English   中英

在构建应用程序后尝试根据命令启动 RabbitListener - RabbitListenerEndpointRegistry 为空

[英]Trying start RabbitListener on command after builded Application - RabbitListenerEndpointRegistry is empty

我搜索了整个 stackOverFlow 并找不到答案。

我需要根据命令启动 RabbitListener - 从 REST 发送请求以启动此侦听器(没有其他选项)。

所以我发现我需要像这样在 Listener 中设置属性: @RabbitListener(queues = "myQueue", id = "listener_id", autoStartup = "false") (当然是 albo 注释@Component )。

我还使用ApplicationContextAwareRabbitListenerEndpointRegistry的实现制作了初始化程序 class,如下所示:

@Slf4j
 @Component
public class ListenerInitializer implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void startListener() {
        RabbitListenerEndpointRegistry listenerRegistry = applicationContext.getBean(RabbitListenerEndpointRegistry.class);
        listenerRegistry.getListenerContainer("listener_id").start();
        log.info("Listener started.");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

当我主要尝试使用方法startListener()时,我收到NullPointerException: null就像RabbitListenerEndpointRegistry不存在一样。 我写的主要是因为有时(每次我进行mvn clean install )它都能正常工作并且一切都很好。 但大多数时候我收到了NullPointerException

@AutowiredApplicationContext相同的情况。

我试过: @Autowired RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry但在那种情况下告诉我RabbitListenerEndpointRegistry bean 不存在(也通过@RequiedArgsConstructor

我也尝试进行如下配置:

@Configuration
@EnableRabbit
class ListenerConfig {

    @Bean
    @DependsOn("listener")
    ListenerInitializer ListenerInitializer() {
        return new ListenerInitializer();
    }

    @Bean(name = "listener")
    Listener listener() {
        return new listener();
    }
}

而且也不起作用。

有人知道我该如何解决吗? 我想我需要尽可能晚地初始化ApplicationContextListenerInitializer的注入,因为需要初始化RabbitListenerEndpointRegistry ,但是怎么做呢?

非常感谢您的任何建议

编辑:我称之为通过 controller 开始

@RequiredArgsConstructor
@RestController
class RestController {

       private final ListenerInitializer listenerInitializer;

    @GetMapping("/startListener")
    ResponseEntity<String> startListener() {
        listenerInitializer.startListener();
        return ResponseEntity.ok("Listener started.");
    }
}

我不知道这是否会以某种方式帮助您,但这是一个完全可用的 Spring 启动应用程序:

@SpringBootApplication
public class So75236736Application {

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

    @Bean
    Listener listener() {
        return new Listener();
    }

    public static class Listener {

        @RabbitListener(queuesToDeclare = @Queue("myQueue"), id = "listener_id", autoStartup = "false")
        void handle(Object body) {
            System.out.println("Received: " + body);
        }

    }

    @Component
    public static class ListenerInitializer implements ApplicationContextAware {

        private ApplicationContext applicationContext;

        public void startListener() {
            RabbitListenerEndpointRegistry listenerRegistry =
                    this.applicationContext.getBean(RabbitListenerEndpointRegistry.class);
            listenerRegistry.getListenerContainer("listener_id").start();
            System.out.println("Listener started");
        }

        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }

    }

    @RestController
    public static class StartListenerController {

        private final ListenerInitializer listenerInitializer;

        public StartListenerController(ListenerInitializer listenerInitializer) {
            this.listenerInitializer = listenerInitializer;
        }

        @GetMapping("/startListener")
        ResponseEntity<String> startListener() {
            this.listenerInitializer.startListener();
            return ResponseEntity.ok("Listener started.");
        }
    }

}

唯一的区别是我没有明确使用@EnableRabbit ,而是依赖于自动配置。 我也没有将ListenerInitializer声明为@Bean ,因为它已经用@Component标记,这足以让 Spring Boot 扫描它。

好的,我找到了解决方案,很抱歉打扰你们。 缺少知识。 我仍然不知道它以前是如何工作的,因为我没有改变任何东西,因为我确定它应该是那样的,但解决方案是移动注释@RabbitListener(queues = "myQueue2", id = "listener_id", autoStartup = "false")从 class 到方法或在方法上添加@RabbitHandler

感谢@Artem Bilan 的帮助!

暂无
暂无

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

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