diff --git a/src/main/java/org/springframework/guice/module/SpringModule.java b/src/main/java/org/springframework/guice/module/SpringModule.java index 7175728..427dc6a 100644 --- a/src/main/java/org/springframework/guice/module/SpringModule.java +++ b/src/main/java/org/springframework/guice/module/SpringModule.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -124,8 +125,10 @@ public class SpringModule extends AbstractModule { if (!type.isInterface() && !ClassUtils.isCglibProxyClass(type)) { bindConditionally(binder(), name, type, typeProvider, namedProvider, bindingAnnotation); } - for (Class iface : ClassUtils.getAllInterfacesForClass(type)) { - bindConditionally(binder(), name, iface, typeProvider, namedProvider, bindingAnnotation); + for (Class iface : getAllSuperInterfaces(new Class[]{type})) { + if (!ClassUtils.isCglibProxyClass(iface)) { + bindConditionally(binder(), name, iface, typeProvider, namedProvider, bindingAnnotation); + } } for (Type iface : type.getGenericInterfaces()) { bindConditionally(binder(), name, iface, typeProvider, namedProvider, bindingAnnotation); @@ -212,6 +215,17 @@ public class SpringModule extends AbstractModule { return Arrays.equals(candidate.getParameterTypes(), current.getParameterTypes()); } + private static Class[] getAllSuperInterfaces(Class[] childInterfaces) { + List allInterfaces = new LinkedList<>(); + for (Class childInterface : childInterfaces) { + allInterfaces.add(childInterface); + allInterfaces.addAll( + Arrays.asList( + getAllSuperInterfaces(childInterface.getInterfaces()))); + } + return allInterfaces.toArray(new Class[0]); + } + @SuppressWarnings({ "rawtypes", "unchecked" }) private void bindConditionally(Binder binder, String name, Type type, Provider typeProvider, Provider namedProvider, Optional bindingAnnotation) { diff --git a/src/test/java/org/springframework/guice/SuperClassTests.java b/src/test/java/org/springframework/guice/SuperClassTests.java new file mode 100644 index 0000000..277f7c8 --- /dev/null +++ b/src/test/java/org/springframework/guice/SuperClassTests.java @@ -0,0 +1,89 @@ +package org.springframework.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.guice.annotation.EnableGuiceModules; + +import static org.junit.Assert.assertTrue; + +public class SuperClassTests { + + @Test + public void testSpringInterface() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + IParent iParent = context.getBean(IParent.class); + assertTrue(iParent instanceof IChildImpl); + } + + @Test + public void testGuiceInterface() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + Injector injector = context.getBean(Injector.class); + IParent iParent = injector.getInstance(IParent.class); + assertTrue(iParent instanceof IChildImpl); + } + + @Test + public void testSpringClass() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + IFoo iFoo = context.getBean(IFoo.class); + assertTrue(iFoo instanceof Foo); + } + + @Test + public void testGuiceClass() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class); + Injector injector = context.getBean(Injector.class); + IFoo iFoo = injector.getInstance(IFoo.class); + assertTrue(iFoo instanceof Foo); + } + + @Configuration + @EnableGuiceModules + static class ModulesConfig { + + @Bean + public IChild iChild() { + return new IChildImpl(); + } + + @Bean + public Foo iFoo() { + return new Foo(); + } + + @Bean + public AbstractModule disableJITModule() { + return new AbstractModule() { + @Override + protected void configure() { + binder().requireExplicitBindings(); + } + }; + } + } + + + public interface IParent { + } + + public interface IChild extends IParent { + + } + + public static class IChildImpl implements IChild { + + } + + public interface IFoo { + + } + + public static class Foo implements IFoo { + + } +}