解析GrpcChannelConfigurer返回lambda含义及builder、name参数来源
decompressionChannelConfigurer方法返回逻辑说明
这个方法是Spring容器的Bean注册方法,@ConditionalOnBean(DecompressorRegistry.class)注解表示只有当Spring容器中已经存在DecompressorRegistry类型的Bean时,才会执行这个方法注册对应的配置器Bean。
方法返回的GrpcChannelConfigurer是一个函数式接口,从接口定义可以看到它继承了BiConsumer<ManagedChannelBuilder<?>, String>,本质就是一个接收两个入参、无返回值的消费型函数,专门用来自定义修改gRPC Channel的构建参数。
你看到的lambda表达式(builder, name) -> builder.decompressorRegistry(registry)就是这个函数式接口的实现,对应接口里的accept方法逻辑:
- 核心逻辑非常直接:拿到传入的Channel构建器对象,给它设置上方法入参注入的
DecompressorRegistry解压缩注册器实例,让这个Channel支持对应的响应解压缩能力 - 表达式里没有用到
name参数不是代码错误,因为解压缩配置是全局通用配置,不需要根据不同Channel的名称做差异化处理,所以直接忽略这个参数即可 - 接口里自带的
andThen默认方法是用来做配置器组合的,可以把多个GrpcChannelConfigurer的逻辑串起来按顺序执行,比如同时设置解压缩、超时时间、拦截器的多个配置器,可以合并成一个按顺序应用到Channel构建器上。
lambda表达式中builder、name参数的来源
这两个参数不需要在业务代码里手动传入,是gRPC Spring整合框架在创建gRPC客户端Channel的流程中自动回调传入的,完整调用流程如下:
- 框架启动阶段会扫描所有Spring容器中类型为
GrpcChannelConfigurer的Bean,统一收集到配置列表中 - 当框架需要为某个gRPC客户端创建Channel时(通常是匹配
@GrpcClient注解标注的客户端注入点),会先创建一个ManagedChannelBuilder实例作为Channel的构建器对象 - 框架会遍历之前收集到的所有
GrpcChannelConfigurer,依次调用每个配置器的accept方法:第一个入参传入当前正在配置的ManagedChannelBuilder实例,也就是lambda里的builder;第二个入参传入当前正在创建的Channel对应的gRPC服务名称,也就是lambda里的name - 所有配置器执行完成后,框架会用配置好的builder生成最终的ManagedChannel实例给客户端使用
注:如果你需要针对不同名称的gRPC服务做差异化配置(比如给某个服务单独设置更长的超时时间),就可以在lambda里判断name的值,再给builder设置不同的参数。
内容的提问来源于stack exchange,提问作者段小言
相关产品推荐
相关产品推荐

