diff --git a/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java b/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java index c531dff..03e1c64 100644 --- a/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java +++ b/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java @@ -25,7 +25,7 @@ import com.google.inject.Key; * * @author Dave Syer */ -class GuiceFactoryBean implements FactoryBean { +public class GuiceFactoryBean implements FactoryBean { private final Key key; private final Class beanType; diff --git a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java index bc19bb1..32e0143 100644 --- a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java +++ b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java @@ -50,6 +50,7 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextException; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; +import org.springframework.core.ResolvableType; import org.springframework.core.annotation.Order; import org.springframework.guice.module.SpringModule; @@ -59,6 +60,7 @@ import org.springframework.guice.module.SpringModule; * * @author Dave Syer * @author Talylor Wicksell + * @author Howard Yuan * */ @Configuration @@ -115,6 +117,7 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor args.addIndexedArgumentValue(0, key.getTypeLiteral().getRawType()); args.addIndexedArgumentValue(1, key); bean.setConstructorArgumentValues(args); + bean.setTargetType(ResolvableType.forType(key.getTypeLiteral().getType())); if (source != null && source instanceof ElementSource) { bean.setResourceDescription( ((ElementSource) source).getDeclaringSource().toString()); @@ -133,7 +136,7 @@ class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostProcessor } private String extractName(Key key) { - final String className = key.getTypeLiteral().getRawType().getSimpleName(); + final String className = key.getTypeLiteral().getType().getTypeName(); String valueAttribute = getValueAttributeForNamed(key.getAnnotation()); if (valueAttribute != null) { return valueAttribute + "_" + className; diff --git a/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java b/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java index 778b35d..60cec90 100644 --- a/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java +++ b/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java @@ -17,6 +17,7 @@ package org.springframework.guice.module; import javax.inject.Provider; +import com.google.inject.Key; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -30,6 +31,7 @@ import com.google.inject.Injector; /** * @author Dave Syer * @author Taylor Wicksell + * @author Howard Yuan * */ class GuiceAutowireCandidateResolver extends ContextAnnotationAutowireCandidateResolver { @@ -78,10 +80,10 @@ class GuiceAutowireCandidateResolver extends ContextAnnotationAutowireCandidateR try { target = beanFactory.doResolveDependency(descriptor, beanName, null, null); } catch (NoSuchBeanDefinitionException e) { - target = injectorProvider.get().getInstance(descriptor.getDependencyType()); + target = injectorProvider.get().getInstance(Key.get(descriptor.getResolvableType().getType())); } if (target == null) { - throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(), + throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(), "Optional dependency not present for lazy injection point"); } return target; diff --git a/src/test/java/org/springframework/guice/ProvidesSupplierWiringTests.java b/src/test/java/org/springframework/guice/ProvidesSupplierWiringTests.java new file mode 100644 index 0000000..0c43fd7 --- /dev/null +++ b/src/test/java/org/springframework/guice/ProvidesSupplierWiringTests.java @@ -0,0 +1,111 @@ +package org.springframework.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Key; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; +import org.junit.Ignore; +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 org.springframework.guice.injector.SpringInjector; + +import javax.inject.Singleton; +import java.util.function.Supplier; + +/** + * Test Generics (e.g., Supplier) not losing type info across bridge in both directions + * + * @author Howard Yuan + */ +public class ProvidesSupplierWiringTests { + + //Test Guice -> Spring direction + @Test + public void testProvidesSupplier() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ModulesConfig.class, FooBar.class); + Foo foo = (Foo)context.getBean(Foo.class); + Bar bar = (Bar)context.getBean(Bar.class); + } + + @Configuration + @EnableGuiceModules + static class ModulesConfig { + @Bean + TestConfig testConfig() { + return new TestConfig(); + } + } + + @Configuration + static class FooBar { + @Bean + Foo foo(Supplier supplier) { + return supplier.get(); + } + + @Bean + Bar bar(Supplier supplier) { + return supplier.get(); + } + } + + static class TestConfig extends AbstractModule { + @Override + protected void configure() { + } + + @Singleton + @Provides + Supplier getFoo() { + return ()->new Foo(); + } + + @Singleton + @Provides + Supplier getBar() { + return ()->new Bar(); + } + } + + static class Foo { + } + + static class Bar { + + } + + //Test Spring -> Guice direction + //ToDo -- Today this direction doesn't work without further work. Ignore the test for now. + @Ignore + @Test + public void testProvidesSupplierSpring() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(FooBarSpring.class); + SpringInjector injector = new SpringInjector(context); + Foo_Spring fooSpring = injector.getInstance(Key.get(new TypeLiteral>(){})).get(); + Bar_Spring barSpring = injector.getInstance(Key.get(new TypeLiteral>(){})).get(); + } + + @Configuration + static class FooBarSpring { + @Bean + Supplier fooSpring() { + return ()->new Foo_Spring(); + } + + @Bean + Bar_Spring barSpring() { + return new Bar_Spring(); + } + } + + static class Foo_Spring { + } + + static class Bar_Spring { + + } + +}