[英]Start @RabbitListener after SpringBoot Application is started
[英]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
)。
我还使用ApplicationContextAware
和RabbitListenerEndpointRegistry
的实现制作了初始化程序 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
。
与@Autowired
的ApplicationContext
相同的情况。
我试过: @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();
}
}
而且也不起作用。
有人知道我该如何解决吗? 我想我需要尽可能晚地初始化ApplicationContext
到ListenerInitializer
的注入,因为需要初始化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.