【问题标题】:Inheritance with SqsListener使用 SqsListener 继承
【发布时间】:2020-10-22 13:30:57
【问题描述】:

我有一个奇怪的情况,我不明白。 我想在一个 bean 中决定,我应该启用还是禁用 SQS 侦听器。 所以我创建了一个带有定义的配置类:

@Bean
MyListener createListener(Features f){
  return f.shouldListen() ? new RealListener() : new MockListener();
}

如你所见,我有这样的继承:

interface MyListener{}
class RealListener implements MyListener{
  @SqsListener(...)
  list handleMessage(SqsMessage message){
    ...
  }
}
class MockListener implements MyListener{}

现在,有趣的部分:

有时有效。

在应用程序重新启动几次后,handleMessage() 方法被调用,但在大多数情况下它并非没有任何异常。队列已创建,所有权限均已到位。 为了使其工作,我需要从 createListener() 方法返回 RealListener 或将 @SqsListener 注释移动到 MyListener 接口中的方法。两者都不是我的选择,因为我不想在启用模拟时调用 AWS。

我尝试过创建条件 bean,但由于 Features 依赖于数据库(更准确地说,是间接 entityManager 依赖),我无法使其正常工作。我尝试过使用抽象类而不是接口,但没有运气。我试图在BeanFactoryPostProcessor 中注册RealListener bean,但这也不起作用(同样的entityManager 依赖问题)。我尝试将注解移至界面,并在启用模拟时使用@ConditionalOnBean@Primary 创建一个空的AmazonSqsClient,但它不起作用。

我可以理解它不起作用,因为必须为带有 @SqsListener 注释的方法的类型创建 bean(而不是它的超类/接口类型),但我有三个这样的 bean 和一个彩票- 有时所有工作,有时一两个,但有时一个都没有。

你有什么建议吗?

【问题讨论】:

    标签: java amazon-web-services amazon-sqs spring-messaging


    【解决方案1】:

    嗯...我已经找到了问题,但如果知道发生了什么,我仍然会很高兴。

    所以...有一个类QueueMessageHandler 使用超类AbstractMethodMessageHandler 中的detectHandlerMethods(...) 方法。此方法使用MethodIntrospector.selectMethods() 选择要扫描的方法。当某些配置类中有@EnableSqs 时,此类会考虑使用@SqsListener 注释的方法。 问题是,在我的项目中,@EnableSqs 注释位于某个文件中 - 不是具有 createListener(...) 方法的文件,也不是 Spring Boot 应用程序的主类。也就是说,@EnableSqs 的类可以在MethodIntrospector.selectMethods() 之前或之后加载。

    输出是:

    1. 我不知道,为什么它在没有继承的情况下也能正常工作,而不能在继承的情况下工作
    2. 为解决此问题,我已将 @EnableSqs 移至项目的主类

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-17
      • 2018-05-23
      • 2019-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      相关资源
      最近更新 更多