diff --git a/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java b/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java index c531dff..1b7eac1 100644 --- a/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java +++ b/src/main/java/org/springframework/guice/annotation/GuiceFactoryBean.java @@ -28,13 +28,16 @@ import com.google.inject.Key; class GuiceFactoryBean implements FactoryBean { private final Key key; private final Class beanType; + private final boolean isSingleton; @Autowired private Injector injector; + - public GuiceFactoryBean(Class beanType, Key key) { + public GuiceFactoryBean(Class beanType, Key key, boolean isSingleton) { this.beanType = beanType; this.key = key; + this.isSingleton = isSingleton; } @Override @@ -49,6 +52,6 @@ class GuiceFactoryBean implements FactoryBean { @Override public boolean isSingleton() { - return true; + return this.isSingleton; } } \ No newline at end of file diff --git a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java index a81e6a6..302ffdb 100644 --- a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java +++ b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java @@ -29,6 +29,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; +import com.google.inject.Scopes; import com.google.inject.Stage; import com.google.inject.name.Named; import com.google.inject.spi.Element; @@ -40,6 +41,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.support.AutowireCandidateQualifier; @@ -118,8 +120,12 @@ class ModuleRegistryConfiguration ConstructorArgumentValues args = new ConstructorArgumentValues(); args.addIndexedArgumentValue(0, key.getTypeLiteral().getRawType()); args.addIndexedArgumentValue(1, key); + args.addIndexedArgumentValue(2, Scopes.isSingleton(binding)); bean.setConstructorArgumentValues(args); bean.setTargetType(ResolvableType.forType(key.getTypeLiteral().getType())); + if(!Scopes.isSingleton(binding)) { + bean.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); + } if (source != null && source instanceof ElementSource) { bean.setResourceDescription( ((ElementSource) source).getDeclaringSource().toString()); diff --git a/src/test/java/org/springframework/guice/ScopingTests.java b/src/test/java/org/springframework/guice/ScopingTests.java new file mode 100644 index 0000000..01c4b0b --- /dev/null +++ b/src/test/java/org/springframework/guice/ScopingTests.java @@ -0,0 +1,90 @@ +package org.springframework.guice; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +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.ScopingTests.CustomScope; +import org.springframework.guice.ScopingTests.SomeCustomScopeDependency; +import org.springframework.guice.ScopingTests.SomeNoScopeDependency; +import org.springframework.guice.ScopingTests.SomeSingletonDependency; +import org.springframework.guice.annotation.EnableGuiceModules; + +import com.google.inject.AbstractModule; +import com.google.inject.Key; +import com.google.inject.Module; +import com.google.inject.Provider; +import com.google.inject.Scope; + +public class ScopingTests { + + @Test + public void verifyScopes() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + ScopingTestsConfig.class); + SomeSingletonDependency someSingletonDependency1 = context.getBean(SomeSingletonDependency.class); + SomeSingletonDependency someSingletonDependency2 = context.getBean(SomeSingletonDependency.class); + + assertNotNull(someSingletonDependency1); + assertNotNull(someSingletonDependency2); + assertEquals(someSingletonDependency1, someSingletonDependency2); + + SomeNoScopeDependency someNoScopeDependency1 = context.getBean(SomeNoScopeDependency.class); + SomeNoScopeDependency someNoScopeDependency2 = context.getBean(SomeNoScopeDependency.class); + + assertNotNull(someNoScopeDependency1); + assertNotNull(someNoScopeDependency2); + assertNotEquals(someNoScopeDependency1, someNoScopeDependency2); + + SomeCustomScopeDependency someCustomScopeDependency1 = context.getBean(SomeCustomScopeDependency.class); + SomeCustomScopeDependency someCustomScopeDependency2 = context.getBean(SomeCustomScopeDependency.class); + + assertNotNull(someCustomScopeDependency1); + assertNotNull(someCustomScopeDependency2); + assertNotEquals(someCustomScopeDependency1, someCustomScopeDependency2); + assertEquals(someCustomScopeDependency1.value, "custom"); + assertEquals(someCustomScopeDependency2.value, "custom"); + + context.close(); + } + + public static class SomeSingletonDependency {} + public static class SomeNoScopeDependency {} + public static class SomeCustomScopeDependency { + String value; + public SomeCustomScopeDependency() {} + public SomeCustomScopeDependency(String value) { + this.value=value; + } + } + public interface CustomScope extends Scope {} + +} + +@EnableGuiceModules +@Configuration +class ScopingTestsConfig { + + @Bean + public Module module() { + return new AbstractModule() { + @Override + protected void configure() { + CustomScope customScope = new CustomScope(){ + @SuppressWarnings("unchecked") + @Override + public Provider scope(Key key, Provider unscoped) { + Provider provider = () -> new SomeCustomScopeDependency("custom"); + return (Provider) provider; + }}; + bind(SomeSingletonDependency.class).asEagerSingleton(); + bind(SomeNoScopeDependency.class); + bind(SomeCustomScopeDependency.class).in(customScope); + } + }; + } +} \ No newline at end of file