diff --git a/core/src/com/google/inject/internal/InjectorImpl.java b/core/src/com/google/inject/internal/InjectorImpl.java index 6bac30eafb..ed594b46fb 100644 --- a/core/src/com/google/inject/internal/InjectorImpl.java +++ b/core/src/com/google/inject/internal/InjectorImpl.java @@ -17,6 +17,7 @@ package com.google.inject.internal; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.inject.internal.Annotations.findScopeAnnotation; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; @@ -783,6 +784,18 @@ BindingImpl createProvidedByBinding( throw errors.recursiveProviderType().toException(); } + // if no scope is specified, look for a scoping annotation on the raw type + if (!scoping.isExplicitlyScoped()) { + int numErrorsBefore = errors.size(); + Class scopeAnnotation = findScopeAnnotation(errors, rawType); + if (scopeAnnotation != null) { + scoping = + Scoping.makeInjectable( + Scoping.forAnnotation(scopeAnnotation), this, errors.withSource(rawType)); + } + errors.throwIfNewErrors(numErrorsBefore); + } + // Assume the provider provides an appropriate type. We double check at runtime. @SuppressWarnings("unchecked") Key> providerKey = (Key>) Key.get(providerType); diff --git a/core/test/com/google/inject/BinderTest.java b/core/test/com/google/inject/BinderTest.java index ff9577db51..b520317b1e 100644 --- a/core/test/com/google/inject/BinderTest.java +++ b/core/test/com/google/inject/BinderTest.java @@ -464,6 +464,8 @@ protected void configure() { assertNotNull(injector.getInstance(HasProvidedBy1.class)); assertNotNull(injector.getInstance(HasImplementedBy1.class)); assertNotSame(HasProvidedBy2.class, injector.getInstance(HasProvidedBy2.class).getClass()); + assertNotSame( + injector.getInstance(HasProvidedBy2.class), injector.getInstance(HasProvidedBy2.class)); assertSame( ExtendsHasImplementedBy2.class, injector.getInstance(HasImplementedBy2.class).getClass()); assertSame(JustAClass.class, injector.getInstance(JustAClass.class).getClass()); diff --git a/core/test/com/google/inject/ScopesTest.java b/core/test/com/google/inject/ScopesTest.java index 409764e6c3..7fb7fa3f81 100644 --- a/core/test/com/google/inject/ScopesTest.java +++ b/core/test/com/google/inject/ScopesTest.java @@ -69,6 +69,7 @@ protected void configure() { bind(NotASingleton.class); bind(ImplementedBySingleton.class).in(Scopes.SINGLETON); bind(ProvidedBySingleton.class).in(Scopes.SINGLETON); + bind(ProvidedByAnnotatedSingleton.class); } }; @@ -83,6 +84,7 @@ protected void setUp() throws Exception { Implementation.nextInstanceId = 0; ProvidedBySingleton.nextInstanceId = 0; ThrowingSingleton.nextInstanceId = 0; + ProvidedByAnnotatedSingleton.nextInstanceId = 0; } public void testSingletons() { @@ -115,6 +117,10 @@ public void testSingletons() { assertSame( injector.getInstance(ProvidedBySingleton.class), injector.getInstance(ProvidedBySingleton.class)); + + assertSame( + injector.getInstance(ProvidedByAnnotatedSingleton.class), + injector.getInstance(ProvidedByAnnotatedSingleton.class)); } public void testJustInTimeAnnotatedSingleton() { @@ -123,12 +129,19 @@ public void testJustInTimeAnnotatedSingleton() { assertSame( injector.getInstance(AnnotatedSingleton.class), injector.getInstance(AnnotatedSingleton.class)); + + assertSame( + injector.getInstance(ProvidedByAnnotatedSingleton.class), + injector.getInstance(ProvidedByAnnotatedSingleton.class)); } public void testSingletonIsPerInjector() { assertNotSame( Guice.createInjector().getInstance(AnnotatedSingleton.class), Guice.createInjector().getInstance(AnnotatedSingleton.class)); + assertNotSame( + Guice.createInjector().getInstance(ProvidedByAnnotatedSingleton.class), + Guice.createInjector().getInstance(ProvidedByAnnotatedSingleton.class)); } public void testOverriddingAnnotation() { @@ -138,12 +151,17 @@ public void testOverriddingAnnotation() { @Override protected void configure() { bind(AnnotatedSingleton.class).in(Scopes.NO_SCOPE); + bind(ProvidedByAnnotatedSingleton.class).in(Scopes.NO_SCOPE); } }); assertNotSame( injector.getInstance(AnnotatedSingleton.class), injector.getInstance(AnnotatedSingleton.class)); + + assertNotSame( + injector.getInstance(ProvidedByAnnotatedSingleton.class), + injector.getInstance(ProvidedByAnnotatedSingleton.class)); } public void testScopingAnnotationsOnAbstractTypeViaBind() { @@ -554,24 +572,39 @@ static class SingletonAndCustomScoped {} @ImplementedBy(Implementation.class) static interface ImplementedBySingleton {} - @ProvidedBy(ImplementationProvider.class) + @ProvidedBy(ProvidedByProvider.class) static class ProvidedBySingleton { static int nextInstanceId; final int instanceId = nextInstanceId++; } + @Singleton + @ProvidedBy(ProvidedByAnnotatedSingletonProvider.class) + static class ProvidedByAnnotatedSingleton { + static int nextInstanceId; + final int instanceId = nextInstanceId++; + } + static class Implementation implements ImplementedBySingleton { static int nextInstanceId; final int instanceId = nextInstanceId++; } - static class ImplementationProvider implements Provider { + static class ProvidedByProvider implements Provider { @Override public ProvidedBySingleton get() { return new ProvidedBySingleton(); } } + static class ProvidedByAnnotatedSingletonProvider + implements Provider { + @Override + public ProvidedByAnnotatedSingleton get() { + return new ProvidedByAnnotatedSingleton(); + } + } + public void testScopeThatGetsAnUnrelatedObject() { Injector injector = Guice.createInjector(