【发布时间】:2021-12-17 10:12:12
【问题描述】:
我正在使用@KafkaListener,我需要一个动态主题名称,所以我使用 SpEL '__listener' 来做到这一点
@PostConstruct
public void init() {
myProps= generateTopicDynamically();
}
@KafkaListener(topics = "#{__listener.myProps}")
public void listenerKafka(@Payload MyObject myObject) {
//Do something with my event
}
效果很好。
主要问题是当我想添加另一个触发某些方面编程的注释时
@MyCustomAnnotationToRecordPerformance @KafkaListener(topics = "#{__listener.myProps}") public void listenerKafka(@Payload MyObject myObject)
这里是方面类
@Aspect
@Configuration
@Slf4j
public class MyCustomAnnotationToRecordPerformanceAspect {
@Pointcut("@annotation(MyCustomAnnotationToRecordPerformance)")
public void annotationMyCustomAnnotationToRecordPerformance() {
}
@Around("annotationMyCustomAnnotationToRecordPerformance()")
public Object doSomething(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
return proceedingJoinPoint.proceed();
}
}
我有这个问题是因为 Spring 在调用 @PostConstruct 之前尝试解析 __listener。
Caused by: java.lang.IllegalArgumentException: @KafKaListener can't resolve 'null' as a String
at org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor.resolveAsString(KafkaListenerAnnotationBeanPostProcessor.java:648)
at org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor.resolveTopics(KafkaListenerAnnotationBeanPostProcessor.java:520)
at org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor.processListener(KafkaListenerAnnotationBeanPostProcessor.java:419)
at org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor.processKafkaListener(KafkaListenerAnnotationBeanPostProcessor.java:370)
at org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor.postProcessAfterInitialization(KafkaListenerAnnotationBeanPostProcessor.java:298)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
... 41 common frames omitted
我尝试调试它 我们可以看到很多CGLIB引用,所以bean已经被代理了,但是所有的属性都是空的。所以我认为 Autowired 和 PostConstruct 方法还没有被调用
目前,我尝试延迟管理 @KafkaListener 的处理器,但我无法找到可以在无需重新定义完全 Kafka 配置的情况下更改它的位置
@EnableKafka 导入 KafkaListenerConfigurationSelector 即 DeferredImportSelector。
这里是关于这门课的评论
A {@link DeferredImportSelector} implementation with the lowest order to import a {@link KafkaBootstrapConfiguration} as late as possible.
所以我认为它已经根据评论尽可能延迟了
我用@Transactional 对其进行了测试,我遇到了同样的问题。
@Transactional
@KafkaListener(topics = "#{__listener.myProps}")
public void listenerKafka(@Payload MyObject myObject)
你有什么想法吗?
我现在看到的唯一选择是将我的班级分成 2 个并创建 2 个 bean。 KafkaListener 方法调用另一个 bean。但我发现必须这样做很奇怪。
提前感谢您的帮助。
【问题讨论】:
-
GitHub 上的MCVE 会有所帮助。重现问题是解决问题的第一步。此外,
@Aspect应该是@Component,而不是@Configuration。我不知道为什么这么多人会弄错。我不能保证它会帮助你解决问题,但它可能会。无论哪种方式,你都应该改变它。配置代理与组件代理的行为方式不同。 -
同意 (MCVE) - 对我来说效果很好。
-
是的,同意@kriegaex,它最初是一个组件,我尝试了不同的想法,忘了回到组件。感谢您的通知。
标签: java spring aop aspectj spring-kafka