Skip to content

Commit 7762601

Browse files
authored
Merge pull request #821 from matyasberry/master
Allow subclasses to be considered as services.
2 parents 49f0c27 + 2e35d48 commit 7762601

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

services-api/src/main/java/io/scalecube/services/Reflect.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import java.lang.reflect.ParameterizedType;
1919
import java.lang.reflect.Type;
2020
import java.util.Arrays;
21-
import java.util.Collection;
2221
import java.util.Collections;
22+
import java.util.HashSet;
2323
import java.util.Map;
24+
import java.util.Set;
2425
import java.util.function.Function;
2526
import java.util.stream.Collectors;
27+
import java.util.stream.Stream;
2628
import org.reactivestreams.Publisher;
2729
import reactor.core.publisher.Flux;
2830
import reactor.core.publisher.Mono;
@@ -255,11 +257,15 @@ public static Map<String, Method> serviceMethods(Class<?> serviceInterface) {
255257
* @param serviceObject with extends service interface with @Service annotation.
256258
* @return service interface class.
257259
*/
258-
public static Collection<Class<?>> serviceInterfaces(Object serviceObject) {
259-
Class<?>[] interfaces = serviceObject.getClass().getInterfaces();
260-
return Arrays.stream(interfaces)
261-
.filter(interfaceClass -> interfaceClass.isAnnotationPresent(Service.class))
262-
.collect(Collectors.toList());
260+
public static Stream<Class<?>> serviceInterfaces(Object serviceObject) {
261+
Class<?> current = serviceObject.getClass();
262+
Set<Class<?>> interfaces = new HashSet<>();
263+
while (current != Object.class) {
264+
interfaces.addAll(Arrays.asList(current.getInterfaces()));
265+
current = current.getSuperclass();
266+
}
267+
return interfaces.stream()
268+
.filter(interfaceClass -> interfaceClass.isAnnotationPresent(Service.class));
263269
}
264270

265271
public static String methodName(Method method) {

services-api/src/main/java/io/scalecube/services/ServiceScanner.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.scalecube.services;
22

3-
import io.scalecube.services.annotations.Service;
43
import io.scalecube.services.annotations.ServiceMethod;
54
import java.util.Arrays;
65
import java.util.Collections;
@@ -22,8 +21,7 @@ private ServiceScanner() {
2221
* @return list of {@code ServiceRegistration}-s
2322
*/
2423
public static List<ServiceRegistration> scanServiceInfo(ServiceInfo serviceInfo) {
25-
return Arrays.stream(serviceInfo.serviceInstance().getClass().getInterfaces())
26-
.filter(serviceInterface -> serviceInterface.isAnnotationPresent(Service.class))
24+
return Reflect.serviceInterfaces(serviceInfo.serviceInstance())
2725
.map(
2826
serviceInterface -> {
2927
Map<String, String> serviceInfoTags = serviceInfo.tags();

services-api/src/test/java/io/scalecube/services/methods/ReflectTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
import io.scalecube.services.CommunicationMode;
99
import io.scalecube.services.Reflect;
10+
import io.scalecube.services.annotations.Service;
1011
import io.scalecube.services.api.ServiceMessage;
1112
import java.lang.reflect.Method;
1213
import java.util.Arrays;
1314
import java.util.stream.Stream;
1415
import org.junit.jupiter.api.Assertions;
16+
import org.junit.jupiter.api.Test;
1517
import org.junit.jupiter.params.ParameterizedTest;
1618
import org.junit.jupiter.params.provider.Arguments;
1719
import org.junit.jupiter.params.provider.MethodSource;
@@ -108,4 +110,31 @@ private interface TestService {
108110

109111
Flux<ServiceMessage> requestChannelMessage(Flux<ServiceMessage> sm);
110112
}
113+
114+
@Service
115+
private interface SimpleService {
116+
public String name();
117+
}
118+
119+
private class ServiceImpl implements SimpleService {
120+
@Override
121+
public String name() {
122+
return "duke";
123+
}
124+
}
125+
126+
private class SubServiceImpl extends ServiceImpl {
127+
128+
}
129+
130+
@Test
131+
public void testSubServiceInterfaces() {
132+
133+
// When:
134+
Stream<Class<?>> interfaces = Reflect.serviceInterfaces(new SubServiceImpl());
135+
// Then:
136+
Assertions.assertEquals(
137+
1,
138+
interfaces.count(), "serviceInterfaces(..) should detect interfaces in SubServiceImpl");
139+
}
111140
}

0 commit comments

Comments
 (0)