Skip to content

Commit 18ea434

Browse files
committed
Polishing and NPE fix
1 parent 71428c6 commit 18ea434

File tree

8 files changed

+188
-113
lines changed

8 files changed

+188
-113
lines changed

docs/en/client/configuration.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public class YourCustomConfiguration {
139139

140140
@Bean
141141
FooService fooServiceBean(@Autowired TestServiceGrpc.TestServiceBlockingStub blockingStub) {
142-
return new FoobarService(blockingStub);
142+
return new FooService(blockingStub);
143143
}
144144

145145
}
@@ -158,6 +158,7 @@ public class BarService {
158158
}
159159

160160
}
161+
````
161162

162163
### GrpcChannelConfigurer
163164

docs/en/client/getting-started.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,17 +191,19 @@ another services.
191191
beanName = "blockingStub",
192192
client = @GrpcClient("test")
193193
)
194-
public static class YourCustomConfiguration {
194+
public class YourCustomConfiguration {
195195

196196
@Bean
197197
FoobarService foobarService(@Autowired TestServiceGrpc.TestServiceBlockingStub blockingStub) {
198198
return new FoobarService(blockingStub);
199199
}
200+
200201
}
201202

202203
@Service
203204
@AllArgsConsturtor
204205
public class FoobarService {
206+
205207
private TestServiceBlockingStub blockingStub;
206208

207209
public String receiveGreeting(String name) {
@@ -213,6 +215,7 @@ public class FoobarService {
213215

214216
}
215217
````
218+
216219
## Additional Topics <!-- omit in toc -->
217220

218221
- *Getting Started*

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.inject.Inject;
2828

2929
import org.springframework.beans.factory.annotation.Autowired;
30+
import org.springframework.context.ApplicationContext;
3031

3132
import io.grpc.CallCredentials;
3233
import io.grpc.CallOptions;
@@ -39,7 +40,7 @@
3940

4041
/**
4142
* An annotation for fields of type {@link Channel} or subclasses of {@link AbstractStub}/gRPC client services. Also
42-
* works for annotated methods that only take a single parameter of the same types. Annotated fields/methods will be
43+
* works for annotated methods that only take a single parameter of these types. Annotated fields/methods will be
4344
* automatically populated/invoked by Spring.
4445
*
4546
* <p>
@@ -59,8 +60,7 @@
5960
* interceptors and applied using {@link ClientInterceptors#interceptForward(Channel, ClientInterceptor...)}.
6061
* </p>
6162
*
62-
* @author Michael ([email protected])
63-
* @since 2016/12/7
63+
* @see GrpcClientBean Add as bean to the {@link ApplicationContext}.
6464
*/
6565
@Target({ElementType.FIELD, ElementType.METHOD})
6666
@Retention(RetentionPolicy.RUNTIME)

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323
import java.lang.annotation.RetentionPolicy;
2424
import java.lang.annotation.Target;
2525

26+
import org.springframework.context.ApplicationContext;
27+
import org.springframework.context.annotation.Configuration;
28+
2629
/**
27-
* Annotation that can be added to `@Configuration` classes to create GrpcClient bean in the ApplicationContext.
30+
* Annotation that can be added to {@link Configuration} classes to add a {@link GrpcClient} bean to the
31+
* {@link ApplicationContext}.
2832
*/
2933
@Target(ElementType.TYPE)
3034
@Repeatable(GrpcClientBeans.class)
@@ -33,17 +37,24 @@
3337

3438
/**
3539
* The type of the bean to create.
40+
*
41+
* @return The type of the bean.
3642
*/
3743
Class<?> clazz();
3844

3945
/**
4046
* The name of the bean to create. If empty, a name will be generated automatically based on the bean class and the
4147
* client name.
48+
*
49+
* @return The optional name of the bean.
4250
*/
4351
String beanName() default "";
4452

4553
/**
4654
* The client definition used to create the channel and grab all properties.
55+
*
56+
* @return The client definition to use.
4757
*/
4858
GrpcClient client();
59+
4960
}

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

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -83,50 +83,80 @@ public GrpcClientBeanPostProcessor(final ApplicationContext applicationContext)
8383
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
8484
Class<?> clazz = bean.getClass();
8585
do {
86-
for (final Field field : clazz.getDeclaredFields()) {
87-
final GrpcClient annotation = AnnotationUtils.findAnnotation(field, GrpcClient.class);
88-
if (annotation != null) {
89-
ReflectionUtils.makeAccessible(field);
90-
ReflectionUtils.setField(field, bean, processInjectionPoint(field, field.getType(), annotation));
91-
}
92-
}
93-
for (final Method method : clazz.getDeclaredMethods()) {
94-
final GrpcClient annotation = AnnotationUtils.findAnnotation(method, GrpcClient.class);
95-
if (annotation != null) {
96-
final Class<?>[] paramTypes = method.getParameterTypes();
97-
if (paramTypes.length != 1) {
98-
throw new BeanDefinitionStoreException(
99-
"Method " + method + " doesn't have exactly one parameter.");
100-
}
101-
ReflectionUtils.makeAccessible(method);
102-
ReflectionUtils.invokeMethod(method, bean,
103-
processInjectionPoint(method, paramTypes[0], annotation));
104-
}
105-
}
86+
processFields(clazz, bean);
87+
processMethods(clazz, bean);
10688

10789
if (isAnnotatedWithConfiguration(clazz)) {
108-
for (final GrpcClientBean annotation : clazz.getAnnotationsByType(GrpcClientBean.class)) {
109-
110-
final String beanNameToCreate = getBeanName(annotation);
111-
try {
112-
final ConfigurableListableBeanFactory beanFactory = getConfigurableBeanFactory();
113-
final Object beanValue =
114-
processInjectionPoint(null, annotation.clazz(), annotation.client());
115-
beanFactory.registerSingleton(beanNameToCreate, beanValue);
116-
} catch (final Exception e) {
117-
throw new BeanCreationException(
118-
"Could not create and register grpc client bean " + beanNameToCreate + " from class " +
119-
clazz.getSimpleName(),
120-
e);
121-
}
122-
}
90+
processGrpcClientBeansAnnotations(clazz);
12391
}
12492

12593
clazz = clazz.getSuperclass();
12694
} while (clazz != null);
12795
return bean;
12896
}
12997

98+
/**
99+
* Processes the bean's fields in the given class.
100+
*
101+
* @param clazz The class to process.
102+
* @param bean The bean to process.
103+
*/
104+
private void processFields(final Class<?> clazz, final Object bean) {
105+
for (final Field field : clazz.getDeclaredFields()) {
106+
final GrpcClient annotation = AnnotationUtils.findAnnotation(field, GrpcClient.class);
107+
if (annotation != null) {
108+
ReflectionUtils.makeAccessible(field);
109+
ReflectionUtils.setField(field, bean, processInjectionPoint(field, field.getType(), annotation));
110+
}
111+
}
112+
}
113+
114+
115+
/**
116+
* Processes the bean's methods in the given class.
117+
*
118+
* @param clazz The class to process.
119+
* @param bean The bean to process.
120+
*/
121+
private void processMethods(final Class<?> clazz, final Object bean) {
122+
for (final Method method : clazz.getDeclaredMethods()) {
123+
final GrpcClient annotation = AnnotationUtils.findAnnotation(method, GrpcClient.class);
124+
if (annotation != null) {
125+
final Class<?>[] paramTypes = method.getParameterTypes();
126+
if (paramTypes.length != 1) {
127+
throw new BeanDefinitionStoreException(
128+
"Method " + method + " doesn't have exactly one parameter.");
129+
}
130+
ReflectionUtils.makeAccessible(method);
131+
ReflectionUtils.invokeMethod(method, bean,
132+
processInjectionPoint(method, paramTypes[0], annotation));
133+
}
134+
}
135+
}
136+
137+
138+
/**
139+
* Processes the given class's {@link GrpcClientBean} annotations.
140+
*
141+
* @param clazz The class to process.
142+
*/
143+
private void processGrpcClientBeansAnnotations(final Class<?> clazz) {
144+
for (final GrpcClientBean annotation : clazz.getAnnotationsByType(GrpcClientBean.class)) {
145+
146+
final String beanNameToCreate = getBeanName(annotation);
147+
try {
148+
final ConfigurableListableBeanFactory beanFactory = getConfigurableBeanFactory();
149+
final Object beanValue =
150+
processInjectionPoint(null, annotation.clazz(), annotation.client());
151+
beanFactory.registerSingleton(beanNameToCreate, beanValue);
152+
} catch (final Exception e) {
153+
throw new BeanCreationException(annotation + " on class " + clazz.getName(), beanNameToCreate,
154+
"Unexpected exception while creating and registering bean",
155+
e);
156+
}
157+
}
158+
}
159+
130160
/**
131161
* Processes the given injection point and computes the appropriate value for the injection.
132162
*
@@ -253,8 +283,7 @@ protected <T> T valueForMember(final String name, final Member injectionTarget,
253283
throw new InvalidPropertyException(injectionTarget.getDeclaringClass(), injectionTarget.getName(),
254284
"Unsupported type " + injectionType.getName());
255285
} else {
256-
throw new InvalidPropertyException(injectionType.getDeclaringClass(), injectionType.getName(),
257-
"Unsupported type " + injectionType.getName());
286+
throw new BeanInstantiationException(injectionType, "Unsupported grpc stub or channel type");
258287
}
259288
}
260289
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,22 @@
2222
import java.lang.annotation.RetentionPolicy;
2323
import java.lang.annotation.Target;
2424

25+
import org.springframework.context.ApplicationContext;
26+
import org.springframework.context.annotation.Configuration;
27+
2528
/**
26-
* Annotation that can be added to `@Configuration` classes to create `GrpcClientBean` beans in the ApplicationContext.
29+
* Annotation that can be added to {@link Configuration} classes to add {@link GrpcClient} beans to the
30+
* {@link ApplicationContext}.
2731
*/
2832
@Target(ElementType.TYPE)
2933
@Retention(RetentionPolicy.RUNTIME)
3034
public @interface GrpcClientBeans {
3135

3236
/**
33-
* Array of bean declarations
37+
* Helper field containing multiple {@link GrpcClientBean} definitions.
38+
*
39+
* @return An array with bean definitions to create.
3440
*/
3541
GrpcClientBean[] value();
42+
3643
}

0 commit comments

Comments
 (0)