From ebfdb1be8eabafc55d0007ff2ec194ddc6f6f15c Mon Sep 17 00:00:00 2001 From: Taylor Wicksell Date: Mon, 24 Aug 2020 16:06:31 -0700 Subject: [PATCH] #80 fix issue where SpringModule did not respect Spring prototype scope --- .../guice/module/SpringModule.java | 12 ++-- .../guice/PrototypeScopedBeanTests.java | 57 +++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 src/test/java/org/springframework/guice/PrototypeScopedBeanTests.java diff --git a/src/main/java/org/springframework/guice/module/SpringModule.java b/src/main/java/org/springframework/guice/module/SpringModule.java index 4d40812..d9edd07 100644 --- a/src/main/java/org/springframework/guice/module/SpringModule.java +++ b/src/main/java/org/springframework/guice/module/SpringModule.java @@ -397,7 +397,7 @@ public class SpringModule extends AbstractModule { private Type type; - private Object result; + private Provider resultProvider; private Optional bindingAnnotation; @@ -421,7 +421,7 @@ public class SpringModule extends AbstractModule { @Override public Object get() { - if (this.result == null) { + if (this.resultProvider == null) { String[] named = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, ResolvableType.forType(type)); @@ -454,22 +454,22 @@ public class SpringModule extends AbstractModule { } } if (names.size() == 1) { - this.result = this.beanFactory.getBean(names.get(0)); + this.resultProvider = () -> this.beanFactory.getBean(names.get(0)); } else { for (String name : named) { if (this.beanFactory.getBeanDefinition(name).isPrimary()) { - this.result = this.beanFactory.getBean(name); + this.resultProvider = () -> this.beanFactory.getBean(name); break; } } - if (this.result == null) { + if (this.resultProvider == null) { throw new ProvisionException( "No primary bean definition for type: " + this.type); } } } - return this.result; + return this.resultProvider.get(); } } diff --git a/src/test/java/org/springframework/guice/PrototypeScopedBeanTests.java b/src/test/java/org/springframework/guice/PrototypeScopedBeanTests.java new file mode 100644 index 0000000..d6d102b --- /dev/null +++ b/src/test/java/org/springframework/guice/PrototypeScopedBeanTests.java @@ -0,0 +1,57 @@ +package org.springframework.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import com.google.inject.Module; +import org.junit.Test; +import org.springframework.context.annotation.*; +import org.springframework.guice.annotation.EnableGuiceModules; + +import javax.inject.Inject; + +import static org.junit.Assert.*; + +public class PrototypeScopedBeanTests { + + @Test + public void testPrototypeScopedBeans() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + ModulesConfig.class); + Injector injector = context.getBean(Injector.class); + GuiceService1 gs1 = injector.getInstance(GuiceService1.class); + GuiceService2 gs2 = injector.getInstance((GuiceService2.class)); + assertNotNull(gs1); + assertNotNull(gs2); + assertNotEquals(gs1.bean, gs2.bean); + } + + @Configuration + @EnableGuiceModules + static class ModulesConfig { + + @Bean + public Module guiceModule() { + return new AbstractModule() { + @Override + protected void configure() { + bind(GuiceService1.class).asEagerSingleton(); + bind(GuiceService2.class).asEagerSingleton(); + } + }; + } + + @Bean + @Scope("prototype") + public PrototypeBean prototypeBean() { + return new PrototypeBean(); + } + } + + public static class PrototypeBean {} + public static class GuiceService1 { + @Inject PrototypeBean bean; + } + public static class GuiceService2 { + @Inject PrototypeBean bean; + } +}