Spring @Bean方法没有执行(被冲掉)

Spring @Bean方法没有执行(被冲掉),第1张

Spring @Bean方法没有执行(被冲掉)

本文解决的问题点:
1、自定义的kafkaTemplate()方法没有执行
2、加了注解@Bean没有执行


背景
不用springboot 自动装配的kafka,想自定义kafka template,就是自己注入kafka的配置参数,如

@Configuration
public class KafkaConfig {

    @Value("${kafka.broker.list}")
    private String bootstrapServer;

    @Value("${kafka.consumer.group.id}")
    private String groupId;

    @Bean
    public KafkaTemplate kafkaTemplate() {
        //创建配置的Map
        Map properties = new HashMap<>();
        //kafka集群地址 [ host:port,host:port ]
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer);
        //key 对应的序列化方式
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        //value 对应的序列化方式
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        //设置是否接收反馈,value必须设置为字符串类型的 1
        properties.put(ProducerConfig.ACKS_CONFIG, "1");
        //设置重试次数
        properties.put(ProducerConfig.RETRIES_CONFIG, 0);
        //设置批处理缓冲大小
        properties.put(ProducerConfig.BATCH_SIZE_CONFIG, 20000000);
        //设置生产者缓冲区大小
        properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432);
        //设置clientId,用于发送给客户端的字符串,用于找日志
        properties.put(ProducerConfig.CLIENT_ID_CONFIG, "kafka.client.demo.id");
        //设置客户端请求的超时时间
        properties.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, 60000);
        //创建ProducerFactory
        ProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(properties);
        //创建KafkaTemplate
        KafkaTemplate kafkaTemplate = new KafkaTemplate<>(producerFactory);
        //返回
        return kafkaTemplate;
    }
}

按理来讲,这里类加了@Configuration
方法上也加了@Bean
服务启动的之后这个方法 kafkaTemplate() 应该被执行,可是却死活没有进来,各种排查,无效!


解决办法
在服务启动类加上配置
@SpringBootApplication(exclude = KafkaAutoConfiguration.class)


原因
经排查spring执行了自动装配
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration#kafkaTemplate

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({KafkaTemplate.class})
@EnableConfigurationProperties({KafkaProperties.class})
@import({KafkaAnnotationDrivenConfiguration.class, KafkaStreamsAnnotationDrivenConfiguration.class})
public class KafkaAutoConfiguration {
    private final KafkaProperties properties;

    public KafkaAutoConfiguration(KafkaProperties properties) {
        this.properties = properties;
    }

    @Bean
    @ConditionalOnMissingBean({KafkaTemplate.class})
    public KafkaTemplate kafkaTemplate(ProducerFactory kafkaProducerFactory, ProducerListener kafkaProducerListener, ObjectProvider messageConverter) {
        KafkaTemplate kafkaTemplate = new KafkaTemplate(kafkaProducerFactory);
        messageConverter.ifUnique(kafkaTemplate::setMessageConverter);
        kafkaTemplate.setProducerListener(kafkaProducerListener);
        kafkaTemplate.setDefaultTopic(this.properties.getTemplate().getDefaultTopic());
        return kafkaTemplate;
    }

因此自定义的bean就没有执行,因为spring配置了冲突只加载一个

spring:
  main:
    allow-bean-definition-overriding: true

所以我们要禁止这个自动装配
所以只需在启动类上加
@SpringBootApplication(exclude = KafkaAutoConfiguration.class)


延伸
类似的redis,mq,mysql等需要自定义的可以去掉自动装配,避免别冲掉

@SpringBootApplication(exclude = RedisAutoConfiguration.class)
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@SpringBootApplication(exclude = MongoAutoConfiguration.class)

// 多个时可以这样
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5709433.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存