From dc2a0b649566475d9fad2ce69e9bd0fcbfa45a08 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Wed, 23 Oct 2019 10:22:13 -0700 Subject: [PATCH] Bind to super types --- .../guice/module/SpringModule.java | 18 +-- .../guice/SuperClassTests.java | 116 +++++++++++++++--- 2 files changed, 112 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/springframework/guice/module/SpringModule.java b/src/main/java/org/springframework/guice/module/SpringModule.java index 7d39e80..5498d4c 100644 --- a/src/main/java/org/springframework/guice/module/SpringModule.java +++ b/src/main/java/org/springframework/guice/module/SpringModule.java @@ -152,9 +152,9 @@ public class SpringModule extends AbstractModule { if (!clazz.isInterface() && !ClassUtils.isCglibProxyClass(clazz)) { bindConditionally(binder(), name, clazz, typeProvider, namedProvider, bindingAnnotation); } - for (Type iface : getAllSuperInterfaces(type, clazz)) { - if (!ClassUtils.isCglibProxyClassName(iface.getTypeName())) { - bindConditionally(binder(), name, iface, typeProvider, namedProvider, bindingAnnotation); + for (Type superType : getAllSuperTypes(type, clazz)) { + if (!ClassUtils.isCglibProxyClassName(superType.getTypeName())) { + bindConditionally(binder(), name, superType, typeProvider, namedProvider, bindingAnnotation); } } for (Type iface : clazz.getGenericInterfaces()) { @@ -242,7 +242,7 @@ public class SpringModule extends AbstractModule { return Arrays.equals(candidate.getParameterTypes(), current.getParameterTypes()); } - private static Set getAllSuperInterfaces(Type originalType, Class clazz) { + private static Set getAllSuperTypes(Type originalType, Class clazz) { Set allInterfaces = new HashSet<>(); TypeLiteral typeToken = TypeLiteral.get(originalType); Queue queue = new LinkedList<>(); @@ -256,13 +256,17 @@ public class SpringModule extends AbstractModule { if (type instanceof Class) { for (Type i : ((Class) type).getInterfaces()) { if (i instanceof Class && ((Class) i).isAssignableFrom(typeToken.getRawType())) { - Type superType = typeToken.getSupertype((Class) i).getType(); - queue.add(superType); - if (!(superType instanceof Class)) { + Type superInterface = typeToken.getSupertype((Class) i).getType(); + queue.add(superInterface); + if (!(superInterface instanceof Class)) { queue.add(i); } } } + if (((Class) type).getSuperclass() != null && ((Class) type).isAssignableFrom(typeToken.getRawType())) { + Type superClass = typeToken.getSupertype(((Class) type).getSuperclass()).getType(); + queue.add(superClass); + } } } return allInterfaces; diff --git a/src/test/java/org/springframework/guice/SuperClassTests.java b/src/test/java/org/springframework/guice/SuperClassTests.java index d9859e7..fdfa2c4 100644 --- a/src/test/java/org/springframework/guice/SuperClassTests.java +++ b/src/test/java/org/springframework/guice/SuperClassTests.java @@ -157,36 +157,108 @@ public class SuperClassTests { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); IFoo iFoo = context.getBean(IFoo.class); assertTrue(iFoo instanceof Foo); + assertTrue(iFoo instanceof SubFoo); + + Foo foo = context.getBean(Foo.class); + assertTrue(foo instanceof SubFoo); } @Test public void testGuiceClass() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + baseTestGuiceClass(ModulesConfig.class); + } + + @Test + public void testImportGuiceClass() { + baseTestGuiceClass(ImportConfig.class); + } + + @Test + public void testComponentScanGuiceClass() { + baseTestGuiceClass(ComponentScanConfig.class); + } + + private void baseTestGuiceClass(Class configClass) { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(configClass); Injector injector = context.getBean(Injector.class); IFoo iFoo = injector.getInstance(IFoo.class); assertTrue(iFoo instanceof Foo); + assertTrue(iFoo instanceof SubFoo); + + Foo foo = injector.getInstance(Foo.class); + assertTrue(foo instanceof SubFoo); } @Test public void testSpringClassWithType() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + baseTestSpringClassWithType(ModulesConfig.class); + } + + @Test + public void testImportSpringClassWithType() { + baseTestSpringClassWithType(ImportConfig.class); + } + + @Test + public void testComponentScanSpringClassWithType() { + baseTestSpringClassWithType(ComponentScanConfig.class); + } + + private void baseTestSpringClassWithType(Class configClass) { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(configClass); String[] stringBeanNames = context.getBeanNamesForType(ResolvableType.forClassWithGenerics(IFooWithType.class, String.class)); assertEquals(1, stringBeanNames.length); assertTrue(context.getBean(stringBeanNames[0]) instanceof StringFoo); + assertTrue(context.getBean(stringBeanNames[0]) instanceof SubStringFoo); + + stringBeanNames = context.getBeanNamesForType(StringFoo.class); + assertEquals(1, stringBeanNames.length); + assertTrue(context.getBean(stringBeanNames[0]) instanceof StringFoo); + assertTrue(context.getBean(stringBeanNames[0]) instanceof SubStringFoo); String[] integerBeanNames = context.getBeanNamesForType(ResolvableType.forClassWithGenerics(IFooWithType.class, Integer.class)); assertEquals(1, integerBeanNames.length); assertTrue(context.getBean(integerBeanNames[0]) instanceof IntegerFoo); + assertTrue(context.getBean(integerBeanNames[0]) instanceof SubIntegerFoo); + + integerBeanNames = context.getBeanNamesForType(IntegerFoo.class); + assertEquals(1, integerBeanNames.length); + assertTrue(context.getBean(integerBeanNames[0]) instanceof IntegerFoo); + assertTrue(context.getBean(integerBeanNames[0]) instanceof SubIntegerFoo); } @Test public void testGuiceClassWithType() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + baseTestGuiceClassWithType(ModulesConfig.class); + } + + @Test + public void testImportGuiceClassWithType() { + baseTestGuiceClassWithType(ImportConfig.class); + } + + @Test + public void testComponentScanGuiceClassWithType() { + baseTestGuiceClassWithType(ComponentScanConfig.class); + } + + private void baseTestGuiceClassWithType(Class configClass) { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(configClass); Injector injector = context.getBean(Injector.class); - IFooWithType stringFoo = injector.getInstance(Key.get(new TypeLiteral>(){})); - assertTrue(stringFoo instanceof StringFoo); - IFooWithType integerFoo = injector.getInstance(Key.get(new TypeLiteral>(){})); - assertTrue(integerFoo instanceof IntegerFoo); + + IFooWithType iFooWithTypeString = injector.getInstance(Key.get(new TypeLiteral>(){})); + assertTrue(iFooWithTypeString instanceof StringFoo); + assertTrue(iFooWithTypeString instanceof SubStringFoo); + + StringFoo stringFoo = injector.getInstance(StringFoo.class); + assertTrue(stringFoo instanceof SubStringFoo); + + IFooWithType iFooWithTypeInteger = injector.getInstance(Key.get(new TypeLiteral>(){})); + assertTrue(iFooWithTypeInteger instanceof IntegerFoo); + assertTrue(iFooWithTypeInteger instanceof SubIntegerFoo); + + IntegerFoo integerFoo = injector.getInstance(IntegerFoo.class); + assertTrue(integerFoo instanceof SubIntegerFoo); } static class DisableJITConfig { @@ -220,19 +292,18 @@ public class SuperClassTests { return new IGrandChildInteger(); } - @Bean - public Foo iFoo() { - return new Foo(); + public SubFoo subFoo() { + return new SubFoo(); } @Bean - public StringFoo stringFoo() { - return new StringFoo(); + public SubStringFoo stringFoo() { + return new SubStringFoo(); } - @Bean IntegerFoo integerFoo() { - return new IntegerFoo(); + @Bean SubIntegerFoo integerFoo() { + return new SubIntegerFoo(); } @@ -240,7 +311,7 @@ public class SuperClassTests { @Configuration @EnableGuiceModules - @Import({IGrandChildImpl.class, IGrandChildString.class, IGrandChildInteger.class}) + @Import({IGrandChildImpl.class, IGrandChildString.class, IGrandChildInteger.class, SubFoo.class, SubStringFoo.class, SubIntegerFoo.class}) static class ImportConfig extends DisableJITConfig { } @@ -299,6 +370,11 @@ public class SuperClassTests { } + @Component + public static class SubFoo extends Foo { + + } + public interface IFooWithType { } @@ -307,8 +383,18 @@ public class SuperClassTests { } + @Component + public static class SubStringFoo extends StringFoo { + + } + public static class IntegerFoo implements IFooWithType { } + @Component + public static class SubIntegerFoo extends IntegerFoo { + + } + }