我正在尝试创建一个注解,以启用自定义Kafka配置来构建一个公共库。我的想法是将我所有的应用程序的Kafka配置变得简单,删除所有样板配置。
所以我想用一个注解来注解我的主应用程序类,并为Kafka侦听器和发布器做所有的配置。
但是我的配置类在spring组件之后初始化,我得到错误:Consider defining a bean of type 'org.springframework.kafka.core.KafkaTemplate' in your configuration
我的注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(KafkaListenerConfigurationSelector.class)
public @interface CustomEnableKafka {}
我的配置选择器:
public class KafkaListenerConfigurationSelector implements DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{CustomKafkaAutoConfiguration.class.getName()};
}
}
最后是我的配置类:
@Slf4j
@Configuration
@EnableConfigurationProperties(CustomKafkaPropertiesMap.class)
@AutoConfigureBefore({KafkaAutoConfiguration.class})
@RequiredArgsConstructor
public class CustomKafkaAutoConfiguration {
//my properties comming from application.yml
private final CustomKafkaPropertiesMap propertiesMap;
private final ConfigurableListableBeanFactory configurableListableBeanFactory;
@PostConstruct
public void postProcessBeanFactory() {
// My logic to register beans
propertiesMap.forEach((configName, properties) -> {
// Configuring my factory with a bean name: myTopicKafkaProducerFactory
var producerFactory = new DefaultKafkaProducerFactory<>(senderProps(properties));
configurableListableBeanFactory.registerSingleton(configName + "KafkaProducerFactory", producerFactory);
//Configuring my kafka template with a bean name: myTopicKafkaTemplate
var kafkaTemplate = new KafkaTemplate<>(producerFactory);
configurableListableBeanFactory.registerSingleton(configName + "KafkaTemplate", kafkaTemplate);
});
}
}
我不知道我怎么能把一个优先权给这个配置比另一个。
编辑:
当我使用限定符myTopicKafkaTemplate
对在客户配置中注册的任何bean执行@Autowired
操作时,如下所示:
@Service
public class TestService {
@Autowired
@Qualifier("myTopicKafkaTemplate")
private KafkaTemplate<String, Object> myTopicKafkaTemplate;
}
然后我收到一条错误消息:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field myTopicKafkaTemplate in com.example.demo.service.TestService required a bean of type 'org.springframework.kafka.core.KafkaTemplate' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
1条答案
按热度按时间brccelvz1#
自动配置不是这样工作的,它不能被导入,也不能像你的
@AutoConfigureBefore({KafkaAutoConfiguration.class})
那样做所有的自动配置工作。考虑在
META-INF/spring.factories
文件中将此CustomKafkaAutoConfiguration
配置为如下条目,而不是自定义注解:编辑
感谢您分享有关您的配置的更多信息!
因此,要使
@Autowired
工作,必须在应用程序上下文中注册一个具有相应名称和类型的bean定义。然而,您的CustomKafkaAutoConfiguration
本身就是bean,它在bean初始化阶段注册这些单例,这对于自动连接候选对象来说是很晚的。考虑实现
ImportBeanDefinitionRegistrar
而不是@PostConstruct
。它不能再是@Configuration
,也不能执行@EnableConfigurationProperties
。您可以将其移到单独的@Configuration
类中,但是在ImportBeanDefinitionRegistrar
中,您必须使用EnvironmentAware
-您不能从ImportBeanDefinitionRegistrar
调用bean。