Я хочу гарантировать, что компонент MyKafkaProducer активируется только при загрузке KafkaAutoConfiguration, поэтому я создал следующий код:
@Service
@ConditionalOnBean(KafkaAutoConfiguration.class)
@RequiredArgsConstructor
public class MyKafkaProducer {
private final KafkaTemplate<String, KafkaEntity> kafkaTemplate;
// omitted...
}
Я проверил список bean-компонентов, созданных после запуска кода по адресу http://localhost:8080/actuator/beans. KafkaAutoConfiguration действительно был создан, как показано ниже.
Но MyKafkaProducer Однако не был создан. Так странно.
"org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration",
"dependencies": [
"spring.kafka-org.springframework.boot.autoconfigure.kafka.KafkaProperties"
]
},
Я изменил @ConditionalOnBean на @ConditionalOnMissingBean в коде и перезапустил его. На этот раз оба компонента KafkaAutoConfiguration и kafkaDlrObserver были успешно созданы.
"org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration",
"dependencies": [
"spring.kafka-org.springframework.boot.autoconfigure.kafka.KafkaProperties"
]
},
"kafkaDlrObserver": {
"aliases": [],
"scope": "singleton",
"type": "com.my.project.kafka.MyKafkaProducer",
"resource": "file [/target/classes/com/my/project/kafka/MyKafkaProducer.class]",
"dependencies": [
"kafkaProducer",
"resultMessageFactory"
]
},
Вопрос:
KafkaAutoConfiguration не создается по умолчанию, что странно, поскольку он отображается в списке компонентов. Почему это?



Из документации класса ConditionalOnBean:
Условие может соответствовать только определениям компонентов, которые уже были обработаны контекстом приложения, поэтому настоятельно рекомендуется использовать это условие только для классов автоконфигурации.
Размещение аннотации @Conditional... в классе @Service или другом компоненте, как показано в вашем примере, ненадежно.
Вместо этого вам следует создать компонент с методом @Bean в классе @AutoConfiguration, примерно так:
@RequiredArgsConstructor
public class MyKafkaProducer {
private final KafkaTemplate<String, KafkaEntity> kafkaTemplate;
// omitted...
}
@AutoConfiguration
@ConditionalOnBean(KafkaAutoConfiguration.class)
public class MyKafkaConfiguration {
@Bean MyKafkaProducer myKafkaProducer(...) {
return new MyKafkaProducer(...);
}
}
Дополнительную информацию о создании классов автоконфигурации см. в документации Spring Boot.
Похоже, это потому, что классы автоматической настройки инициализируются после конфигурации приложения и компонентов. Вы можете попробовать создать свою собственную автоматическую конфигурацию с такими условиями, и она будет работать так, как вы ожидаете.