diff --git a/README.md b/README.md index 3cfaa3b..b338cdd 100644 --- a/README.md +++ b/README.md @@ -128,16 +128,16 @@ exclude the `@Bean` type from the `Injector` bindings using the * So far there is no support for the Guice SPI methods in `SpringInjector` so tooling may not work. It wouldn't be hard to do. -* `SpringInjector` only knows about raw types, so it ignores - additional meta-information in factory requests (like - annotations). Should be easy enough to fix, but some compromises - might hav eto be made. +* `SpringInjector` only knows about raw types and bean names, so it + ignores additional meta-information in factory requests (like + annotations other than `@Named`). Should be easy enough to fix, but + some compromises might have to be made. * `SpringInjector` has no support for creating child or parent `Injectors`. Probably not difficult. * `SpringModule` treats all beans as singletons. -* `SpringModule` binds all interfaces of a bean it can find. This - should work out OK, as long as those interfaces are not needed for - injection (and if there is no `@Primary` bean). +* `SpringModule` binds all interfaces and all names of a bean it can + find. This should work out OK, as long as those interfaces are not + needed for injection (and if there is no `@Primary` bean). diff --git a/pom.xml b/pom.xml index c1e0264..e7f3160 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework spring-framework-bom - 4.2.5.RELEASE + ${spring.version} pom import @@ -50,6 +50,7 @@ 1.6 UTF-8 UTF-8 + 4.2.6.RELEASE diff --git a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java index 7065cd5..9b4bc79 100644 --- a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java +++ b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java @@ -37,6 +37,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.name.Named; @Configuration @Order(Ordered.HIGHEST_PRECEDENCE + 10) @@ -51,33 +52,39 @@ public class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostPr private void mapBindings(Injector injector, BeanDefinitionRegistry registry) { for (Entry, Binding> entry : injector.getBindings().entrySet()) { - if (entry.getKey().getTypeLiteral().getRawType().equals(Injector.class) || + if (entry.getKey().getTypeLiteral().getRawType().equals(Injector.class) || "spring-guice".equals(entry.getValue().getSource().toString())) { continue; } - + entry.getValue().getKey().toString(); RootBeanDefinition bean = new RootBeanDefinition(GuiceFactoryBean.class); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.addIndexedArgumentValue(0, entry.getKey().getTypeLiteral().getRawType()); args.addIndexedArgumentValue(1, entry.getValue().getProvider()); bean.setConstructorArgumentValues(args); - registry.registerBeanDefinition(entry.getValue().getKey().toString(), bean); + registry.registerBeanDefinition(extractName(entry.getValue().getKey()), bean); } - + if(injector.getParent() != null) { mapBindings(injector.getParent(), registry); } - + ((ConfigurableListableBeanFactory) registry).registerResolvableDependency(Injector.class, injector); } + private String extractName(Key key) { + if (key.getAnnotation() instanceof Named) { + return ((Named) key.getAnnotation()).value(); + } + return key.getTypeLiteral().getRawType().getSimpleName(); + } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - - + + } @Override @@ -86,6 +93,7 @@ public class ModuleRegistryConfiguration implements BeanDefinitionRegistryPostPr modules.add(new SpringModule(this.applicationContext)); Injector injector = createInjector(modules); mapBindings(injector, registry); + ((ConfigurableListableBeanFactory) registry).registerSingleton(Injector.class.getName(), injector); } @Override diff --git a/src/main/java/org/springframework/guice/injector/CompositeAutowireCandidateResolver.java b/src/main/java/org/springframework/guice/injector/CompositeAutowireCandidateResolver.java new file mode 100644 index 0000000..dacf55c --- /dev/null +++ b/src/main/java/org/springframework/guice/injector/CompositeAutowireCandidateResolver.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.guice.injector; + +import java.util.List; + +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.beans.factory.support.AutowireCandidateResolver; + +/** + * @author Dave Syer + * + */ +public class CompositeAutowireCandidateResolver implements AutowireCandidateResolver { + + private List delegates; + + public CompositeAutowireCandidateResolver(List delegates) { + this.delegates = delegates; + } + + @Override + public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, + DependencyDescriptor descriptor) { + for (AutowireCandidateResolver delegate : this.delegates) { + if (delegate.isAutowireCandidate(bdHolder, descriptor)) { + return true; + } + } + return false; + } + + @Override + public Object getSuggestedValue(DependencyDescriptor descriptor) { + for (AutowireCandidateResolver delegate : this.delegates) { + Object value = delegate.getSuggestedValue(descriptor); + if (value!=null) { + return value; + } + } + return null; + } + + @Override + public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, + String beanName) { + for (AutowireCandidateResolver delegate : this.delegates) { + Object value = delegate.getLazyResolutionProxyIfNecessary(descriptor, beanName); + if (value!=null) { + return value; + } + } + return null; + } + +} diff --git a/src/main/java/org/springframework/guice/injector/GuiceAutowireCandidateResolver.java b/src/main/java/org/springframework/guice/injector/GuiceAutowireCandidateResolver.java new file mode 100644 index 0000000..145108b --- /dev/null +++ b/src/main/java/org/springframework/guice/injector/GuiceAutowireCandidateResolver.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.guice.injector; + +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.beans.factory.support.AutowireCandidateResolver; +import org.springframework.core.ResolvableType; + +/** + * @author Dave Syer + * + */ +public class GuiceAutowireCandidateResolver implements AutowireCandidateResolver { + + @Override + public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, + DependencyDescriptor descriptor) { + return false; + } + + @Override + public Object getSuggestedValue(DependencyDescriptor descriptor) { + ResolvableType resolvable = descriptor.getResolvableType(); + return null; + } + + @Override + public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, + String beanName) { + return null; + } + +} diff --git a/src/main/java/org/springframework/guice/injector/SpringInjector.java b/src/main/java/org/springframework/guice/injector/SpringInjector.java index f6362bf..faf3838 100644 --- a/src/main/java/org/springframework/guice/injector/SpringInjector.java +++ b/src/main/java/org/springframework/guice/injector/SpringInjector.java @@ -30,13 +30,14 @@ import com.google.inject.Module; import com.google.inject.Provider; import com.google.inject.Scope; import com.google.inject.TypeLiteral; +import com.google.inject.name.Named; import com.google.inject.spi.TypeConverterBinding; public class SpringInjector implements Injector { - + private Injector injector; private DefaultListableBeanFactory beanFactory; - + public SpringInjector(ApplicationContext context) { this.beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory(); if (context.getBeanNamesForType(Injector.class, true, false).length>0) { @@ -46,7 +47,7 @@ public class SpringInjector implements Injector { @Override public void injectMembers(Object instance) { - beanFactory.autowireBean(instance); + this.beanFactory.autowireBean(instance); } @Override @@ -54,7 +55,7 @@ public class SpringInjector implements Injector { return new MembersInjector() { @Override public void injectMembers(T instance) { - beanFactory.autowireBean(instance); + SpringInjector.this.beanFactory.autowireBean(instance); } }; } @@ -97,47 +98,54 @@ public class SpringInjector implements Injector { @Override public Provider getProvider(Key key) { // TODO: support for other metadata in the key - @SuppressWarnings("unchecked") - Provider provider = (Provider) getProvider(key.getTypeLiteral().getRawType()); - return provider; - } - - @Override - public Provider getProvider(Class type) { - if (beanFactory.getBeanNamesForType(type, true, false).length==0) { - if (injector!=null && injector.getExistingBinding(Key.get(type))!=null) { - return injector.getProvider(type); + Class type = key.getTypeLiteral().getRawType(); + final String name = extractName(key); + if (this.beanFactory.getBeanNamesForType(type, true, false).length==0) { + if (this.injector!=null) { + return this.injector.getProvider(key); } // TODO: use prototype scope? - beanFactory.registerBeanDefinition(type.getSimpleName(), new RootBeanDefinition(type)); + this.beanFactory.registerBeanDefinition(name, new RootBeanDefinition(type)); } - final Class cls = type; + if (this.beanFactory.containsBean(name) && this.beanFactory.isTypeMatch(name, type)) { + return new Provider() { + @SuppressWarnings("unchecked") + @Override + public T get() { + return (T) SpringInjector.this.beanFactory.getBean(name); + } + }; + } + @SuppressWarnings("unchecked") + final Class cls = (Class) type; return new Provider() { @Override public T get() { - return beanFactory.getBean(cls); + return SpringInjector.this.beanFactory.getBean(cls); } }; } + private String extractName(Key key) { + if (key.getAnnotation() instanceof Named) { + return ((Named) key.getAnnotation()).value(); + } + return key.getTypeLiteral().getRawType().getSimpleName(); + } + + @Override + public Provider getProvider(Class type) { + return getProvider(Key.get(type)); + } + @Override public T getInstance(Key key) { - // TODO: support for other metadata in the key - @SuppressWarnings("unchecked") - T provider = (T) getInstance(key.getTypeLiteral().getRawType()); - return provider; + return getProvider(key).get(); } @Override public T getInstance(Class type) { - if (beanFactory.getBeanNamesForType(type, true, false).length==0) { - if (injector!=null && injector.getExistingBinding(Key.get(type))!=null) { - return injector.getInstance(type); - } - // TODO: use prototype scope? - beanFactory.registerBeanDefinition(type.getSimpleName(), new RootBeanDefinition(type)); - } - return beanFactory.getBean(type); + return getInstance(Key.get(type)); } @Override @@ -164,5 +172,5 @@ public class SpringInjector implements Injector { public Set getTypeConverterBindings() { return null; } - + } \ No newline at end of file diff --git a/src/main/java/org/springframework/guice/module/SpringModule.java b/src/main/java/org/springframework/guice/module/SpringModule.java index 76ce070..382b75f 100644 --- a/src/main/java/org/springframework/guice/module/SpringModule.java +++ b/src/main/java/org/springframework/guice/module/SpringModule.java @@ -28,6 +28,7 @@ import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import com.google.inject.name.Names; /** * @author Dave Syer @@ -54,14 +55,14 @@ public class SpringModule implements Module { @Override public void configure(Binder binder) { - for (String name : beanFactory.getBeanDefinitionNames()) { - BeanDefinition definition = beanFactory.getBeanDefinition(name); + for (String name : this.beanFactory.getBeanDefinitionNames()) { + BeanDefinition definition = this.beanFactory.getBeanDefinition(name); if (definition.isAutowireCandidate() && definition.getRole() == AbstractBeanDefinition.ROLE_APPLICATION) { - Class type = beanFactory.getType(name); + Class type = this.beanFactory.getType(name); @SuppressWarnings("unchecked") final Class cls = (Class) type; final String beanName = name; - Provider provider = new BeanFactoryProvider(beanFactory, beanName, type); + Provider provider = new BeanFactoryProvider(this.beanFactory, beanName, type); if (!cls.isInterface() && !ClassUtils.isCglibProxyClass(cls)) { bindConditionally(binder, name, cls, provider); } @@ -75,18 +76,19 @@ public class SpringModule implements Module { } private void bindConditionally(Binder binder, String name, Class type, Provider provider) { - if (bound.get(type) != null) { + if (this.bound.get(type) != null) { // Only bind one provider for each type return; // TODO: named beans } - if (!matcher.matches(name, type)) { + if (!this.matcher.matches(name, type)) { return; } if (type.getName().startsWith("com.google.inject")) { return; } binder.withSource("spring-guice").bind(type).toProvider(provider); - bound.put(type, provider); + binder.withSource("spring-guice").bind(type).annotatedWith(Names.named(name)).toProvider(provider); + this.bound.put(type, provider); } private static class BeanFactoryProvider implements Provider { @@ -107,24 +109,24 @@ public class SpringModule implements Module { @Override public Object get() { - if (result == null) { - String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, type); + if (this.result == null) { + String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, this.type); if (names.length == 1) { - result = beanFactory.getBean(name, type); + this.result = this.beanFactory.getBean(this.name, this.type); } else { for (String name : names) { - if (beanFactory.getBeanDefinition(name).isPrimary()) { - result = beanFactory.getBean(name, type); + if (this.beanFactory.getBeanDefinition(name).isPrimary()) { + this.result = this.beanFactory.getBean(name, this.type); break; } } - if (result == null) { - throw new ProvisionException("No primary bean definition for type: " + type); + if (this.result == null) { + throw new ProvisionException("No primary bean definition for type: " + this.type); } } } - return result; + return this.result; } } @@ -137,7 +139,7 @@ public class SpringModule implements Module { @Override public boolean matches(String name, Class type) { - for (BindingTypeMatcher matcher : matchers) { + for (BindingTypeMatcher matcher : this.matchers) { if (matcher.matches(name, type)) { return true; } diff --git a/src/test/java/org/springframework/guice/AbstractCompleteWiringTests.java b/src/test/java/org/springframework/guice/AbstractCompleteWiringTests.java index e848191..09272ff 100644 --- a/src/test/java/org/springframework/guice/AbstractCompleteWiringTests.java +++ b/src/test/java/org/springframework/guice/AbstractCompleteWiringTests.java @@ -4,11 +4,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import javax.inject.Inject; +import javax.inject.Named; import org.junit.Before; import org.junit.Test; import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.name.Names; public abstract class AbstractCompleteWiringTests { @@ -16,7 +19,7 @@ public abstract class AbstractCompleteWiringTests { @Before public void init() { - injector = createInjector(); + this.injector = createInjector(); } protected abstract Injector createInjector(); @@ -24,42 +27,52 @@ public abstract class AbstractCompleteWiringTests { @Test public void injectInstance() { Bar bar = new Bar(); - injector.injectMembers(bar); + this.injector.injectMembers(bar); assertNotNull(bar.service); } @Test public void memberInjector() { Bar bar = new Bar(); - injector.getMembersInjector(Bar.class).injectMembers(bar); + this.injector.getMembersInjector(Bar.class).injectMembers(bar); assertNotNull(bar.service); } @Test public void getInstanceUnbound() { - assertNotNull(injector.getInstance(Foo.class)); + assertNotNull(this.injector.getInstance(Foo.class)); } @Test public void getInstanceBound() { - assertNotNull(injector.getInstance(Service.class)); + assertNotNull(this.injector.getInstance(Service.class)); } @Test public void getInstanceBoundWithNoInterface() { - Baz instance = injector.getInstance(Baz.class); + Baz instance = this.injector.getInstance(Baz.class); assertNotNull(instance); - assertEquals(instance, injector.getInstance(Baz.class)); + assertEquals(instance, this.injector.getInstance(Baz.class)); } @Test public void getProviderUnbound() { - assertNotNull(injector.getProvider(Foo.class).get()); + assertNotNull(this.injector.getProvider(Foo.class).get()); } @Test public void getProviderBound() { - assertNotNull(injector.getProvider(Service.class).get()); + assertNotNull(this.injector.getProvider(Service.class).get()); + } + + @Test + public void getNamedInstance() { + assertNotNull(this.injector.getInstance(Key.get(Thang.class, Names.named("thing")))); + } + + @Test + public void getNamedInjectedInstance() { + assertNotNull(this.injector.getInstance(Thing.class).thang); } public interface Service { @@ -95,4 +108,17 @@ public abstract class AbstractCompleteWiringTests { } + public static class Thing { + + private Thang thang; + + @Inject + public void setThang(@Named("thing") Thang thang) { + this.thang = thang; + } + + } + + public static class Thang { + } } diff --git a/src/test/java/org/springframework/guice/GuiceWiringTests.java b/src/test/java/org/springframework/guice/GuiceWiringTests.java index a1e7b54..e77ae20 100644 --- a/src/test/java/org/springframework/guice/GuiceWiringTests.java +++ b/src/test/java/org/springframework/guice/GuiceWiringTests.java @@ -18,6 +18,7 @@ import javax.inject.Singleton; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.name.Names; /** * @author Dave Syer @@ -36,7 +37,8 @@ public class GuiceWiringTests extends AbstractCompleteWiringTests { protected void configure() { bind(Service.class).to(MyService.class); bind(Baz.class).in(Singleton.class); + bind(Thang.class).annotatedWith(Names.named("thing")).to(Thang.class); } } - + } diff --git a/src/test/java/org/springframework/guice/NativeGuiceTests.java b/src/test/java/org/springframework/guice/NativeGuiceTests.java new file mode 100644 index 0000000..a6397fd --- /dev/null +++ b/src/test/java/org/springframework/guice/NativeGuiceTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.guice; + +import static org.junit.Assert.assertNotNull; + +import javax.inject.Inject; + +import org.junit.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.name.Names; + +/** + * @author Dave Syer + * + */ +public class NativeGuiceTests { + + @Inject + private Foo bar; + + @Test + public void test() { + Injector app = Guice.createInjector(new TestConfig()); + NativeGuiceTests instance = app.getInstance(NativeGuiceTests.class); + assertNotNull(instance.bar); + } + + public static class TestConfig extends AbstractModule { + @Override + protected void configure() { + bind(Foo.class).annotatedWith(Names.named("bar")).to(Foo.class); + } + } + + public static class Foo {} +} diff --git a/src/test/java/org/springframework/guice/annotation/ModuleBeanWiringTests.java b/src/test/java/org/springframework/guice/annotation/ModuleBeanWiringTests.java index bf0449b..3731a52 100644 --- a/src/test/java/org/springframework/guice/annotation/ModuleBeanWiringTests.java +++ b/src/test/java/org/springframework/guice/annotation/ModuleBeanWiringTests.java @@ -15,6 +15,10 @@ package org.springframework.guice.annotation; import static org.junit.Assert.assertNotNull; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -25,6 +29,7 @@ import org.springframework.guice.injector.SpringInjector; import com.google.inject.AbstractModule; import com.google.inject.Injector; +import com.google.inject.Provides; /** * @author Dave Syer @@ -36,23 +41,23 @@ public class ModuleBeanWiringTests extends AbstractCompleteWiringTests { @Override protected Injector createInjector() { - context = new AnnotationConfigApplicationContext(); - context.register(TestConfig.class); - context.refresh(); - return new SpringInjector(context); + this.context = new AnnotationConfigApplicationContext(); + this.context.register(TestConfig.class); + this.context.refresh(); + return new SpringInjector(this.context); } @Test public void bindToSpringBeanFromGuiceModule() throws Exception { - assertNotNull(context.getBean(Spam.class)); + assertNotNull(this.context.getBean(Spam.class)); } @EnableGuiceModules @Configuration public static class TestConfig extends AbstractModule { - + @Autowired Service service; - + @Override protected void configure() { bind(Service.class).to(MyService.class); @@ -62,7 +67,20 @@ public class ModuleBeanWiringTests extends AbstractCompleteWiringTests { public Spam spam(Service service) { return new Spam(service); } - } + + @Provides + @Named("thing") + public Thang thing() { + return new Thang(); + } + + @Provides + @Inject + @Singleton + public Baz baz(Service service) { + return new Baz(service); + } +} protected static class Spam { public Spam(Service service) { diff --git a/src/test/java/org/springframework/guice/annotation/ModuleNamedBeanWiringTests.java b/src/test/java/org/springframework/guice/annotation/ModuleNamedBeanWiringTests.java new file mode 100644 index 0000000..3573da2 --- /dev/null +++ b/src/test/java/org/springframework/guice/annotation/ModuleNamedBeanWiringTests.java @@ -0,0 +1,96 @@ +/* + * Copyright 2013-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.springframework.guice.annotation; + +import static org.junit.Assert.assertNotNull; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.guice.AbstractCompleteWiringTests; +import org.springframework.guice.injector.SpringInjector; + +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import com.google.inject.Provides; + +/** + * @author Dave Syer + * + */ +public class ModuleNamedBeanWiringTests extends AbstractCompleteWiringTests { + + private AnnotationConfigApplicationContext context; + + @Override + protected Injector createInjector() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(TestConfig.class); + this.context.refresh(); + return new SpringInjector(this.context); + } + + @Test + public void bindToSpringBeanFromGuiceModule() throws Exception { + assertNotNull(this.context.getBean(Spam.class)); + } + + @EnableGuiceModules + @Configuration + public static class TestConfig extends AbstractModule { + + @Autowired Service service; + + @Override + protected void configure() { + bind(Service.class).to(MyService.class); + } + + @Bean + public Spam spam(Service service) { + return new Spam(service); + } + + @Provides + @Named("thing") + public Thang thing() { + return new Thang(); + } + + @Provides + @Named("other") + public Thang other() { + return new Thang(); + } + + @Provides + @Inject + @Singleton + public Baz baz(Service service) { + return new Baz(service); + } +} + + protected static class Spam { + public Spam(Service service) { + } + } + +} diff --git a/src/test/java/org/springframework/guice/injector/SpringWiringTests.java b/src/test/java/org/springframework/guice/injector/SpringWiringTests.java index 5db95d2..02ae7a6 100644 --- a/src/test/java/org/springframework/guice/injector/SpringWiringTests.java +++ b/src/test/java/org/springframework/guice/injector/SpringWiringTests.java @@ -40,6 +40,14 @@ public class SpringWiringTests extends AbstractCompleteWiringTests { public Service service() { return new MyService(); } + @Bean + public Thang thing() { + return new Thang(); + } + @Bean + public Thang other() { + return new Thang(); + } } } diff --git a/src/test/java/org/springframework/guice/module/SpringModuleWiringTests.java b/src/test/java/org/springframework/guice/module/SpringModuleWiringTests.java index 4ac6342..5c4364c 100644 --- a/src/test/java/org/springframework/guice/module/SpringModuleWiringTests.java +++ b/src/test/java/org/springframework/guice/module/SpringModuleWiringTests.java @@ -51,6 +51,17 @@ public class SpringModuleWiringTests extends AbstractCompleteWiringTests { public Baz baz() { return new Baz(service()); } + + @Bean + public Thang thing() { + return new Thang(); + } + + @Bean + public Thing that() { + return new Thing(); + } + } }