SpringBoot 2.3.7升级至2.5.4 KafkaStreams自动配置Bean缺失问题
问题根因
你遇到的报错是Spring Cloud 2020.0.3对应版本的Spring Cloud Function、Spring Cloud Stream Kafka Streams组件的默认行为导致的:
- Spring Cloud Function 3.x及以上版本会自动扫描所有返回函数式接口的Bean,将其识别为待注册的函数处理组件,会为这类Bean自动生成内部注册用的附属Bean,命名规则就是
&<原Bean名>_registration,其中&是Spring内部用于标记FactoryBean本身的固定前缀,_registration是函数注册Bean的固定后缀。 - Spring Cloud Stream Kafka Streams的自动配置类
KafkaStreamsFunctionAutoConfiguration会默认尝试将所有识别到的函数Bean绑定为Kafka Streams处理器,你的getRestTemplate是返回函数式接口的普通业务Bean,不是用于流处理的函数,因此自动配置在绑定过程中会尝试查找根本不存在的附属注册Bean,触发报错。 - Spring Boot 2.3.7对应版本的Spring Cloud Function没有这类自动扫描绑定逻辑,因此可以正常运行。
解决方案
可根据你的项目实际情况选择以下任意一种方案:
- 方案一:配置指定Spring Cloud Function扫描的函数范围
在application.yml/application.properties中添加配置,如果你没有需要用到的流处理函数,直接配置:
如果你有其他需要被识别的流处理函数,将函数名按英文逗号分隔填入即可,不要包含spring: cloud: function: definition: nonegetRestTemplate,框架就不会扫描识别这个业务函数Bean。 - 方案二:关闭不需要的自动配置
如果你的项目没有使用Kafka Streams的函数绑定能力,直接在启动类排除对应的自动配置类即可:@SpringBootApplication(exclude = [org.springframework.cloud.stream.binder.kafka.streams.function.KafkaStreamsFunctionAutoConfiguration::class]) - 方案三:修改Bean定义避免被识别为函数组件
不要直接将函数式接口作为Bean返回,自定义一个包装类承载这个函数逻辑,示例如下:
注入时调整注入类型即可:class RestTemplateProvider(val getImpl: (RestCallRequest) -> RestTemplate?) @Bean fun getRestTemplate(): RestTemplateProvider { return RestTemplateProvider { restCallRequest -> getRestTemplateNameForUrl(restCallRequest.url)?.let(::getOrBuildRestTemplate) } }@Autowired private lateinit var getRestTemplate: RestTemplateProvider // 使用时调用getRestTemplate.getImpl(request)即可
内容的提问来源于stack exchange,提问作者goya
相关产品推荐
相关产品推荐

