Bind all super interfaces

This commit is contained in:
Kevin Wang
2019-10-04 10:46:05 -07:00
committed by Taylor Wicksell
parent ee75c7a7a5
commit 4308f7498b
2 changed files with 105 additions and 2 deletions

View File

@@ -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<Class> 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<Annotation> bindingAnnotation) {

View File

@@ -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 {
}
}