使用SqsListener继承

问题描述

我有一个我不理解的奇怪情况。 我想决定要启用还是禁用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()方法,但是在大多数情况下,并非没有例外。队列已创建,所有权限均已到位。 为了使其正常工作,我需要从RealListener方法返回createListener()或将@SqsListener注释移至MyListener界面中的方法。两者都不是我的选择,因为启用模拟后,我不想调用AWS。

我尝试了条件豆的创建,但是由于Features依赖于数据库(更确切地说,是间接的objectManager依赖关系),所以我无法使其工作。我尝试了抽象类而不是接口,但是没有运气。我尝试在RealListener注册beanfactoryPostProcessor bean,但这也行不通(相同的entityManager依赖问题)。我尝试将注释移至界面,并在启用了模拟功能后将@ConditionalOnBean@Primary一起使用,以创建一个空的AmazonSqsClient,但它不起作用。

我可以理解它是行不通的,因为必须使用@SqsListener注释的方法为该类型的bean创建(而不是其超级类/接口类型),但是我有三个这样的bean,并且彩票-有时全部正常,有时一两个,但有时都不起作用。

您有什么建议吗?

解决方法

好吧...我已经找到了问题,但是知道发生了什么仍然很好。

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

输出为:

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...