Spring自动配置之---KafkaAutoConfiguration学习

1、是Spring提供的对Kafka进行的自动化配置

@Configuration
@ConditionalOnClass(KafkaTemplate.class)
@EnableConfigurationProperties(KafkaProperties.class)
@Import({ KafkaAnnotationDrivenConfiguration.class,
      KafkaStreamsAnnotationDrivenConfiguration.class })
public class KafkaAutoConfiguration {

   private final KafkaProperties properties;

   private final RecordMessageConverter messageConverter;

   public KafkaAutoConfiguration(KafkaProperties properties,
         ObjectProvider<RecordMessageConverter> messageConverter) {
      this.properties = properties;
      this.messageConverter = messageConverter.getIfUnique();
   }

   @Bean
   @ConditionalOnMissingBean(KafkaTemplate.class)
   public KafkaTemplate<?, ?> kafkaTemplate(
         ProducerFactory<Object, Object> kafkaProducerFactory,
         ProducerListener<Object, Object> kafkaProducerListener) {
      KafkaTemplate<Object, Object> kafkaTemplate = new KafkaTemplate<>(
            kafkaProducerFactory);
      if (this.messageConverter != null) {
         kafkaTemplate.setMessageConverter(this.messageConverter);
      }
      kafkaTemplate.setProducerListener(kafkaProducerListener);
      kafkaTemplate.setDefaultTopic(this.properties.getTemplate().getDefaultTopic());
      return kafkaTemplate;
   }

   @Bean
   @ConditionalOnMissingBean(ProducerListener.class)
   public ProducerListener<Object, Object> kafkaProducerListener() {
      return new LoggingProducerListener<>();
   }

   @Bean
   @ConditionalOnMissingBean(ConsumerFactory.class)
   public ConsumerFactory<?, ?> kafkaConsumerFactory() {
      return new DefaultKafkaConsumerFactory<>(
            this.properties.buildConsumerProperties());
   }

   @Bean
   @ConditionalOnMissingBean(ProducerFactory.class)
   public ProducerFactory<?, ?> kafkaProducerFactory() {
      DefaultKafkaProducerFactory<?, ?> factory = new DefaultKafkaProducerFactory<>(
            this.properties.buildProducerProperties());
      String transactionIdPrefix = this.properties.getProducer()
            .getTransactionIdPrefix();
      if (transactionIdPrefix != null) {
         factory.setTransactionIdPrefix(transactionIdPrefix);
      }
      return factory;
   }

   @Bean
   @ConditionalOnProperty(name = "spring.kafka.producer.transaction-id-prefix")
   @ConditionalOnMissingBean
   public KafkaTransactionManager<?, ?> kafkaTransactionManager(
         ProducerFactory<?, ?> producerFactory) {
      return new KafkaTransactionManager<>(producerFactory);
   }

   @Bean
   @ConditionalOnProperty(name = "spring.kafka.jaas.enabled")
   @ConditionalOnMissingBean
   public KafkaJaasLoginModuleInitializer kafkaJaasInitializer() throws IOException {
      KafkaJaasLoginModuleInitializer jaas = new KafkaJaasLoginModuleInitializer();
      Jaas jaasProperties = this.properties.getJaas();
      if (jaasProperties.getControlFlag() != null) {
         jaas.setControlFlag(jaasProperties.getControlFlag());
      }
      if (jaasProperties.getLoginModule() != null) {
         jaas.setLoginModule(jaasProperties.getLoginModule());
      }
      jaas.setOptions(jaasProperties.getOptions());
      return jaas;
   }

   @Bean
   @ConditionalOnMissingBean
   public KafkaAdmin kafkaAdmin() {
      KafkaAdmin kafkaAdmin = new KafkaAdmin(this.properties.buildAdminProperties());
      kafkaAdmin.setFatalIfBrokerNotAvailable(this.properties.getAdmin().isFailFast());
      return kafkaAdmin;
   }

}

知识点1:

@ConditionalOnClass(KafkaTemplate.class)

只有路径中有KafkaTemplate.class时此配置才生效,即需要引入kafkaTemplate的jar包

知识点2:

@EnableConfigurationProperties(KafkaProperties.class)

如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component,那么在IOC容器中是获取不到properties 配置文件转化的bean。说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。 

@ConfigurationProperties(prefix = "spring.kafka")
public class KafkaProperties {...

通过yaml文件将属性装载入bean,配置如下:

spring:
  kafka:
    consumer:
      group-id: ${spring.application.name}
      enable-auto-commit: false
      auto-offset-reset: latest
    producer:
      client-id: ${spring.application.name}
      retries: 3

....

知识点3: 

@ConditionalOnMissingBean(KafkaTemplate.class)

没有KafkaTemplate实例时会生效,Spring容器或者所有父容器中需要存在至少一个KafkaTemplate类的实例

知识点4:

@Bean
@ConditionalOnMissingBean(KafkaTemplate.class)
public KafkaTemplate<?, ?> kafkaTemplate(
      ProducerFactory<Object, Object> kafkaProducerFactory,
      ProducerListener<Object, Object> kafkaProducerListener) {
   KafkaTemplate<Object, Object> kafkaTemplate = new KafkaTemplate<>(
         kafkaProducerFactory);
   if (this.messageConverter != null) {
      kafkaTemplate.setMessageConverter(this.messageConverter);
   }
   kafkaTemplate.setProducerListener(kafkaProducerListener);
   kafkaTemplate.setDefaultTopic(this.properties.getTemplate().getDefaultTopic());
   return kafkaTemplate;
}

对于@Bean 修饰的方法的入参,会从Spring容器中获取同类型的实例 ,多个则取按名获取,否则会报错。类似@Autowired

知识点5:

@ConditionalOnProperty(name = "spring.kafka.producer.transaction-id-prefix")

 @ConditionalOnProperty能够控制某个configuration是否生效。具体操作是通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值,如果该值为空,则返回false;如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。如果返回值为false,则该configuration不生效;为true则生效。

猜你喜欢

转载自blog.csdn.net/lbh199466/article/details/89515806