Skip to content

Commit 2ff58cd

Browse files
committed
[BREAKING] Simplify interceptor registry (Fixes #338)
- Lazy collect interceptors and global interceptor configurers - Changed API of global interceptor registry and configurers Now it is possible to define a global interceptor using the respective annotation in a @configuration. It is no longer required for (auto) configs with global interceptor and their configurers to be loaded before the grpc channel/server auto config.
1 parent 1043e47 commit 2ff58cd

File tree

25 files changed

+583
-201
lines changed

25 files changed

+583
-201
lines changed

docs/en/client/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ public GrpcChannelConfigurer keepAliveClientConfigurer() {
128128

129129
There are three ways to add a `ClientInterceptor` to your channel.
130130

131-
- Define the `ClientInterceptor` as a global interceptor using either the `@GrpcGlobalClientInterceptor` annotation or
132-
the `GlobalClientInterceptorRegistry`
131+
- Define the `ClientInterceptor` as a global interceptor using either the `@GrpcGlobalClientInterceptor` annotation,
132+
or a `GlobalClientInterceptorConfigurer`
133133
- Explicitly list them in the `@GrpcClient#interceptors` or `@GrpcClient#interceptorNames` field
134134
- Use a `StubTransformer` and call `stub.withInterceptors(ClientInterceptor... interceptors)`
135135

docs/en/server/configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This section describes how you can configure your grpc-spring-boot-starter appli
1010
- [Changing the Server Port](#changing-the-server-port)
1111
- [Enabling the InProcessServer](#enabling-the-inprocessserver)
1212
- [Configuration via Beans](#configuration-via-beans)
13+
- [ServerInterceptor](#serverinterceptor)
1314
- [GrpcServerConfigurer](#grpcserverconfigurer)
1415

1516
## Additional topics <!-- omit in toc -->
@@ -86,6 +87,15 @@ First of all most of the beans can be replaced by custom ones, that you can conf
8687
If you don't wish to go that far, you can use classes such as `GrpcServerConfigurer` to configure the server and other
8788
components without losing the features provided by this library.
8889

90+
### ServerInterceptor
91+
92+
There are three ways to add a `ServerInterceptor` to your server.
93+
94+
- Define the `ServerInterceptor` as a global interceptor using either the `@GrpcGlobalServerInterceptor` annotation,
95+
or a `GlobalServerInterceptorConfigurer`
96+
- Explicitly list them in the `@GrpcService#interceptors` or `@GrpcService#interceptorNames` field
97+
- Use a `GrpcServerConfigurer` and call `serverBuilder.intercept(ServerInterceptor interceptor)`
98+
8999
### GrpcServerConfigurer
90100

91101
The grpc server configurer allows you to add your custom configuration to grpc's `ServerBuilder`s.

examples/cloud-grpc-client/src/main/java/net/devh/boot/grpc/examples/cloud/client/GlobalClientInterceptorConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@
2222
import org.springframework.core.Ordered;
2323
import org.springframework.core.annotation.Order;
2424

25-
import net.devh.boot.grpc.client.interceptor.GlobalClientInterceptorConfigurer;
25+
import io.grpc.ClientInterceptor;
2626

2727
@Order(Ordered.LOWEST_PRECEDENCE)
2828
@Configuration(proxyBeanMethods = false)
2929
public class GlobalClientInterceptorConfiguration {
3030

3131
@Bean
32-
public GlobalClientInterceptorConfigurer globalInterceptorConfigurerAdapter() {
33-
return registry -> registry.addClientInterceptors(new LogGrpcInterceptor());
32+
ClientInterceptor logClientInterceptor() {
33+
return new LogGrpcInterceptor();
3434
}
3535

3636
}

examples/cloud-grpc-server/src/main/java/net/devh/boot/grpc/examples/cloud/server/GlobalInterceptorConfiguration.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717

1818
package net.devh.boot.grpc.examples.cloud.server;
1919

20-
import org.springframework.context.annotation.Bean;
2120
import org.springframework.context.annotation.Configuration;
2221

23-
import net.devh.boot.grpc.server.interceptor.GlobalServerInterceptorConfigurer;
22+
import io.grpc.ServerInterceptor;
23+
import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor;
2424

2525
@Configuration(proxyBeanMethods = false)
2626
public class GlobalInterceptorConfiguration {
2727

28-
@Bean
29-
public GlobalServerInterceptorConfigurer globalInterceptorConfigurerAdapter() {
30-
return registry -> registry.addServerInterceptors(new LogGrpcInterceptor());
28+
@GrpcGlobalServerInterceptor
29+
ServerInterceptor logServerInterceptor() {
30+
return new LogGrpcInterceptor();
3131
}
3232

3333
}

examples/local-grpc-client/src/main/java/net/devh/boot/grpc/examples/local/client/GlobalClientInterceptorConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@
2222
import org.springframework.core.Ordered;
2323
import org.springframework.core.annotation.Order;
2424

25-
import net.devh.boot.grpc.client.interceptor.GlobalClientInterceptorConfigurer;
25+
import io.grpc.ClientInterceptor;
2626

2727
@Order(Ordered.LOWEST_PRECEDENCE)
2828
@Configuration(proxyBeanMethods = false)
2929
public class GlobalClientInterceptorConfiguration {
3030

3131
@Bean
32-
public GlobalClientInterceptorConfigurer globalInterceptorConfigurerAdapter() {
33-
return registry -> registry.addClientInterceptors(new LogGrpcInterceptor());
32+
ClientInterceptor logClientInterceptor() {
33+
return new LogGrpcInterceptor();
3434
}
3535

3636
}

examples/local-grpc-server/src/main/java/net/devh/boot/grpc/examples/local/server/GlobalInterceptorConfiguration.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,17 @@
1717

1818
package net.devh.boot.grpc.examples.local.server;
1919

20-
import org.springframework.context.annotation.Bean;
2120
import org.springframework.context.annotation.Configuration;
2221

23-
import net.devh.boot.grpc.server.interceptor.GlobalServerInterceptorConfigurer;
24-
import net.devh.boot.grpc.server.interceptor.GlobalServerInterceptorRegistry;
22+
import io.grpc.ServerInterceptor;
23+
import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor;
2524

2625
@Configuration(proxyBeanMethods = false)
2726
public class GlobalInterceptorConfiguration {
2827

29-
@Bean
30-
public GlobalServerInterceptorConfigurer globalInterceptorConfigurerAdapter() {
31-
return new GlobalServerInterceptorConfigurer() {
32-
@Override
33-
public void addServerInterceptors(GlobalServerInterceptorRegistry registry) {
34-
registry.addServerInterceptors(new LogGrpcInterceptor());
35-
}
36-
};
28+
@GrpcGlobalServerInterceptor
29+
ServerInterceptor logServerInterceptor() {
30+
return new LogGrpcInterceptor();
3731
}
3832

3933
}

grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/autoconfigure/GrpcClientAutoConfiguration.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,15 @@ GrpcChannelsProperties grpcChannelsProperties() {
9292

9393
@ConditionalOnMissingBean
9494
@Bean
95-
GlobalClientInterceptorRegistry globalClientInterceptorRegistry() {
96-
return new GlobalClientInterceptorRegistry();
95+
GlobalClientInterceptorRegistry globalClientInterceptorRegistry(final ApplicationContext applicationContext) {
96+
return new GlobalClientInterceptorRegistry(applicationContext);
9797
}
9898

9999
@Bean
100-
AnnotationGlobalClientInterceptorConfigurer annotationGlobalClientInterceptorConfigurer() {
101-
return new AnnotationGlobalClientInterceptorConfigurer();
100+
@Lazy
101+
AnnotationGlobalClientInterceptorConfigurer annotationGlobalClientInterceptorConfigurer(
102+
final ApplicationContext applicationContext) {
103+
return new AnnotationGlobalClientInterceptorConfigurer(applicationContext);
102104
}
103105

104106
/**

grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/autoconfigure/GrpcClientTraceAutoConfiguration.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2121
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2222
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
23-
import org.springframework.context.annotation.Bean;
2423
import org.springframework.context.annotation.Configuration;
2524

2625
import brave.grpc.GrpcTracing;
27-
import net.devh.boot.grpc.client.interceptor.GlobalClientInterceptorConfigurer;
26+
import io.grpc.ClientInterceptor;
27+
import net.devh.boot.grpc.client.interceptor.GrpcGlobalClientInterceptor;
2828
import net.devh.boot.grpc.client.interceptor.OrderedClientInterceptor;
2929
import net.devh.boot.grpc.common.autoconfigure.GrpcCommonTraceAutoConfiguration;
3030
import net.devh.boot.grpc.common.util.InterceptorOrder;
@@ -44,14 +44,13 @@ public class GrpcClientTraceAutoConfiguration {
4444
* Configures a global client interceptor that applies brave's tracing logic to the requests.
4545
*
4646
* @param grpcTracing The grpc tracing bean.
47-
* @return The globalTraceClientInterceptorConfigurer bean.
47+
* @return The tracing client interceptor bean.
4848
*/
49-
@Bean
50-
public GlobalClientInterceptorConfigurer globalTraceClientInterceptorConfigurer(final GrpcTracing grpcTracing) {
51-
return registry -> registry.addClientInterceptors(
52-
new OrderedClientInterceptor(
53-
grpcTracing.newClientInterceptor(),
54-
InterceptorOrder.ORDER_TRACING_METRICS + 1));
49+
@GrpcGlobalClientInterceptor
50+
ClientInterceptor globalTraceClientInterceptorConfigurer(final GrpcTracing grpcTracing) {
51+
return new OrderedClientInterceptor(
52+
grpcTracing.newClientInterceptor(),
53+
InterceptorOrder.ORDER_TRACING_METRICS + 1);
5554
}
5655

5756
}

grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/interceptor/AnnotationGlobalClientInterceptorConfigurer.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717

1818
package net.devh.boot.grpc.client.interceptor;
1919

20-
import org.springframework.beans.factory.annotation.Autowired;
20+
import static com.google.common.collect.Maps.transformValues;
21+
import static java.util.Objects.requireNonNull;
22+
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Map.Entry;
26+
2127
import org.springframework.context.ApplicationContext;
2228

2329
import io.grpc.ClientInterceptor;
@@ -31,17 +37,36 @@
3137
@Slf4j
3238
public class AnnotationGlobalClientInterceptorConfigurer implements GlobalClientInterceptorConfigurer {
3339

34-
@Autowired
35-
private ApplicationContext context;
40+
private final ApplicationContext applicationContext;
41+
42+
/**
43+
* Creates a new AnnotationGlobalClientInterceptorConfigurer.
44+
*
45+
* @param applicationContext The application context to fetch the {@link GrpcGlobalClientInterceptor} annotated
46+
* {@link ClientInterceptor} beans from.
47+
*/
48+
public AnnotationGlobalClientInterceptorConfigurer(final ApplicationContext applicationContext) {
49+
this.applicationContext = requireNonNull(applicationContext, "applicationContext");
50+
}
51+
52+
/**
53+
* Helper method used to get the {@link GrpcGlobalClientInterceptor} annotated {@link ClientInterceptor}s from the
54+
* application context.
55+
*
56+
* @return A map containing the global interceptor beans.
57+
*/
58+
protected Map<String, ClientInterceptor> getClientInterceptorBeans() {
59+
return transformValues(this.applicationContext.getBeansWithAnnotation(GrpcGlobalClientInterceptor.class),
60+
ClientInterceptor.class::cast);
61+
}
3662

3763
@Override
38-
public void addClientInterceptors(final GlobalClientInterceptorRegistry registry) {
39-
this.context.getBeansWithAnnotation(GrpcGlobalClientInterceptor.class)
40-
.forEach((name, bean) -> {
41-
ClientInterceptor interceptor = (ClientInterceptor) bean;
42-
log.debug("Registering GlobalClientInterceptor: {} ({})", name, interceptor);
43-
registry.addClientInterceptors(interceptor);
44-
});
64+
public void configureClientInterceptors(final List<ClientInterceptor> interceptors) {
65+
for (final Entry<String, ClientInterceptor> entry : getClientInterceptorBeans().entrySet()) {
66+
final ClientInterceptor interceptor = entry.getValue();
67+
log.debug("Registering GlobalClientInterceptor: {} ({})", entry.getKey(), interceptor);
68+
interceptors.add(interceptor);
69+
}
4570
}
4671

4772
}

grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/interceptor/GlobalClientInterceptorConfigurer.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,24 @@
1717

1818
package net.devh.boot.grpc.client.interceptor;
1919

20+
import java.util.List;
21+
2022
import io.grpc.ClientInterceptor;
2123

2224
/**
23-
* This configurer can be used to register new global {@link ClientInterceptor}s.
25+
* A bean that can be used to configure global {@link ClientInterceptor}s.
2426
*
2527
* @author Daniel Theuke ([email protected])
2628
*/
2729
@FunctionalInterface
2830
public interface GlobalClientInterceptorConfigurer {
2931

3032
/**
31-
* Adds the {@link ClientInterceptor}s that should be registered globally to the given registry.
33+
* Configures the given list of client interceptors, possibly adding new elements, removing unwanted elements, or
34+
* reordering the existing ones.
3235
*
33-
* @param registry The registry the interceptors should be added to.
36+
* @param interceptors A mutable list of client interceptors to configure.
3437
*/
35-
void addClientInterceptors(GlobalClientInterceptorRegistry registry);
38+
void configureClientInterceptors(List<ClientInterceptor> interceptors);
3639

3740
}

0 commit comments

Comments
 (0)