我有一个奇怪的情况,我不明白。我想在bean中决定是启用还是禁用SQS侦听器。因此,我创建了一个具有定义的config类:
@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{}现在,有趣的是:
It 有时可以工作。
在应用程序很少重新启动之后,就会调用handleMessage()方法,但在大多数情况下,它并不是无一例外的。已创建队列,所有权限均已到位。为了使其正常工作,我需要从RealListener方法返回createListener(),或者将@SqsListener注释移到MyListener接口中的方法。这两个选项对我来说都不是,因为我不想在启用模拟时调用AWS。
我尝试过使用条件bean创建,但是由于Features依赖于DB (更准确地说,是间接的entityManager依赖),所以我无法使它工作。我尝试过抽象类,而不是接口,但没有成功。我尝试在RealListener中注册BeanFactoryPostProcessor bean,但这也不起作用(同样的entityManager依赖问题)。我尝试将注释移到接口上,并在启用模拟时使用@ConditionalOnBean和@Primary创建一个空的AmazonSqsClient,但是它不起作用。
我可以理解它不起作用,因为这个bean必须为带有@SqsListener注释的方法的类型创建(而不是它的超类/接口类型),但是我有三个这样的bean和一个彩票--有时全部工作,有时是一两个,但有时没有。
你有什么意见建议?
发布于 2020-10-23 08:28:05
好吧..。我已经发现了这个问题,但是知道发生了什么还是很好的。
所以..。有一个类QueueMessageHandler使用来自超类AbstractMethodMessageHandler的detectHandlerMethods(...)方法。此方法使用MethodIntrospector.selectMethods()选择要扫描的方法。当某些配置类中有@SqsListener时,该类将考虑用@EnableSqs注释的方法。问题是,在我的项目中,@EnableSqs注释位于某个文件中--不是使用createListener(...)方法的文件,也不是Spring应用程序的主类。这意味着,可以在@EnableSqs之前或之后加载带有MethodIntrospector.selectMethods()的类。
产出如下:
我不知道为什么没有继承就能很好地工作,并且不使用inheritance
@EnableSqs移到了项目的主类中
https://stackoverflow.com/questions/64483348
复制相似问题