一个gRPC客户端,其通道的名称取自存根类的名称
在 Spring-Grpc 中,我可以把声明为bean的客户端配置为使用命名通道:
@Bean
MyServiceGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
return MyServiceGrpc.newBlockingStub(channels.createChannel("my-service"));
}
@Bean
AnotherServiceGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
return AnotherServiceGrpc.newBlockingStub(channels.createChannel("another-service"));
}
然后在我的应用程序属性中配置这些通道。例如:
spring.grpc.client.channels.my-service.address=0.0.0.0:9090
spring.grpc.client.channels.another-service.address=0.0.0.0:9091
或者,我也可以通过注解来创建它们:
@ImportGrpcClients(target = "my-service", types = MyServiceGrpc.SimpleBlockingStub.class)
@ImportGrpcClients(target = "another-service", types = AnotherServiceGrpc.SimpleBlockingStub.class)
我希望只使用这个注解并结合包扫描,而不是逐一列出所有客户端,并根据服务的名称来推断通道的名称。
@ImportGrpcClients(basePackages = "mycompany.clients.com")
这是否可能?
解决方案
我通过扩展GrpcClientFactory并注册以替换默认实现来实现了这一点。我本来希望有更简单的方式来做这件事,但正如Max在 他的回答 中所说的那样,看来这是一个刻意的设计决策,不让它变得容易。无论如何,这是我的解决方案:
public class MyGrpcClientFactory extends GrpcClientFactory {
@Override
public <S> S getClient(String target, Class<S> type, Class<?> factory) {
if ("default".equals(target)) {
target = getChannelName(type);
}
return super.getClient(target, type, factory);
}
private static String getChannelName(Class<?> type) {
String name = type.getEnclosingClass().getSimpleName();
name = name.substring(0, name.indexOf("Grpc"));
// Change to kebab-case.
return String.join("-", StringUtils.splitByCharacterTypeCamelCase(name)).toLowerCase();
}
/**
* Registers the AssetTestGrpcClientFactory so that it replaces the standard GrpcClientFactory.
*/
public static class Registrar implements BeanRegistrar {
@Override
public void register(BeanRegistry registry, Environment env) {
registry.registerBean(
GrpcClientFactory.class.getName(), MyGrpcClientFactory.class, BeanRegistry.Spec::primary);
}
}
}
然后你需要把Registrar导入到你的 @Configuration 类中:
@Import(MyGrpcClientFactory.Registrar.class)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。