Split bean registration and creation for stubs

GrpcClientRegistry was responsible for both, which causes lifecycle
issues when users don't follow recommendations. This change
pushes the bean registration firmly down a level into an
ImportBeanDefinitionRegistrar. Also helps with AOT because the AOT
processor only runs the IBDR at build time.
This commit is contained in:
Dave Syer
2025-04-01 11:49:59 +01:00
parent 326c075b36
commit a3d7ba643d
13 changed files with 437 additions and 492 deletions

View File

@@ -22,7 +22,7 @@ import org.springframework.experimental.boot.test.context.EnableDynamicProperty;
import org.springframework.experimental.boot.test.context.OAuth2ClientProviderIssuerUri;
import org.springframework.grpc.client.ChannelBuilderOptions;
import org.springframework.grpc.client.ImportGrpcClients;
import org.springframework.grpc.client.GrpcClientRegistryCustomizer;
import org.springframework.grpc.client.GrpcClientFactoryCustomizer;
import org.springframework.grpc.client.interceptor.security.BearerTokenAuthenticationInterceptor;
import org.springframework.grpc.sample.proto.HelloReply;
import org.springframework.grpc.sample.proto.HelloRequest;
@@ -41,7 +41,7 @@ import io.grpc.reflection.v1.ServerReflectionResponse;
import io.grpc.stub.StreamObserver;
@SpringBootTest(properties = { "spring.grpc.server.port=0",
"spring.grpc.client.channels.stub.address=static://0.0.0.0:${local.grpc.port}" })
"spring.grpc.client.default-channel.address=static://0.0.0.0:${local.grpc.port}" })
@DirtiesContext
public class GrpcServerApplicationTests {
@@ -115,6 +115,7 @@ public class GrpcServerApplicationTests {
@EnableDynamicProperty
@ImportGrpcClients(target = "stub",
types = { SimpleGrpc.SimpleBlockingStub.class, ServerReflectionGrpc.ServerReflectionStub.class })
@ImportGrpcClients(target = "secure", prefix = "secure", types = { SimpleGrpc.SimpleBlockingStub.class })
static class ExtraConfiguration {
private String token;
@@ -129,13 +130,9 @@ public class GrpcServerApplicationTests {
}
@Bean
GrpcClientRegistryCustomizer stubs(ObjectProvider<ClientRegistrationRepository> context) {
return registry -> registry
.channel("stub",
ChannelBuilderOptions.defaults()
.withInterceptors(List.of(new BearerTokenAuthenticationInterceptor(() -> token(context)))))
.prefix("secure")
.register(SimpleGrpc.SimpleBlockingStub.class);
GrpcClientFactoryCustomizer stubs(ObjectProvider<ClientRegistrationRepository> context) {
return registry -> registry.channel("secure", ChannelBuilderOptions.defaults()
.withInterceptors(List.of(new BearerTokenAuthenticationInterceptor(() -> token(context)))));
}
private String token(ObjectProvider<ClientRegistrationRepository> context) {

View File

@@ -15,10 +15,9 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.grpc.client.BlockingStubFactory;
import org.springframework.grpc.client.ChannelBuilderOptions;
import org.springframework.grpc.client.GrpcClientFactoryCustomizer;
import org.springframework.grpc.client.ImportGrpcClients;
import org.springframework.grpc.client.GrpcClientRegistryCustomizer;
import org.springframework.grpc.client.interceptor.security.BasicAuthenticationInterceptor;
import org.springframework.grpc.sample.proto.HelloReply;
import org.springframework.grpc.sample.proto.HelloRequest;
@@ -109,17 +108,14 @@ public class GrpcServerApplicationTests {
@TestConfiguration(proxyBeanMethods = false)
@ImportGrpcClients(target = "stub", prefix = "unsecured", types = { SimpleGrpc.SimpleBlockingStub.class })
@ImportGrpcClients(target = "secure", types = { SimpleGrpc.SimpleBlockingStub.class })
@ImportGrpcClients(target = "default", types = { ServerReflectionGrpc.ServerReflectionStub.class })
static class ExtraConfiguration {
@Bean
GrpcClientRegistryCustomizer basicStubs() {
return registry -> registry
.channel("stub",
ChannelBuilderOptions.defaults()
.withInterceptors(List.of(new BasicAuthenticationInterceptor("user", "user"))))
.scan(BlockingStubFactory.class)
.packageClasses(SimpleGrpc.class);
GrpcClientFactoryCustomizer basicStubs() {
return registry -> registry.channel("secure", ChannelBuilderOptions.defaults()
.withInterceptors(List.of(new BasicAuthenticationInterceptor("user", "user"))));
}
}