diff --git a/pom.xml b/pom.xml index 2af52a3..7cda92c 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,11 @@ spring-boot-starter-test test + + org.eclipse.jetty.orbit + javax.mail.glassfish + 1.4.1.v201005082020 + diff --git a/src/test/java/demo/AbstractCompleteWiringTests.java b/src/test/java/demo/AbstractCompleteWiringTests.java index edb0438..309f811 100644 --- a/src/test/java/demo/AbstractCompleteWiringTests.java +++ b/src/test/java/demo/AbstractCompleteWiringTests.java @@ -20,6 +20,20 @@ public abstract class AbstractCompleteWiringTests { protected abstract Injector createInjector(); + @Test + public void injectInstance() { + Bar bar = new Bar(); + injector.injectMembers(bar); + assertNotNull(bar.service); + } + + @Test + public void memberInjector() { + Bar bar = new Bar(); + injector.getMembersInjector(Bar.class).injectMembers(bar); + assertNotNull(bar.service); + } + @Test public void getInstanceUnbound() { assertNotNull(injector.getInstance(Foo.class)); @@ -30,6 +44,16 @@ public abstract class AbstractCompleteWiringTests { assertNotNull(injector.getInstance(Service.class)); } + @Test + public void getProviderUnbound() { + assertNotNull(injector.getProvider(Foo.class).get()); + } + + @Test + public void getProviderBound() { + assertNotNull(injector.getProvider(Service.class).get()); + } + interface Service { } @@ -44,4 +68,15 @@ public abstract class AbstractCompleteWiringTests { } + public static class Bar { + + private Service service; + + @Inject + public void setService(Service service) { + this.service = service; + } + + } + } diff --git a/src/test/java/demo/HybridWiringTests.java b/src/test/java/demo/ModuleBeanWiringTests.java similarity index 94% rename from src/test/java/demo/HybridWiringTests.java rename to src/test/java/demo/ModuleBeanWiringTests.java index bd147c5..3cd4efd 100644 --- a/src/test/java/demo/HybridWiringTests.java +++ b/src/test/java/demo/ModuleBeanWiringTests.java @@ -22,7 +22,7 @@ import com.google.inject.Injector; * @author Dave Syer * */ -public class HybridWiringTests extends AbstractCompleteWiringTests { +public class ModuleBeanWiringTests extends AbstractCompleteWiringTests { @Override protected Injector createInjector() { diff --git a/src/test/java/demo/SpringInjector.java b/src/test/java/demo/SpringInjector.java index cb17e68..a912f6c 100644 --- a/src/test/java/demo/SpringInjector.java +++ b/src/test/java/demo/SpringInjector.java @@ -45,17 +45,22 @@ public class SpringInjector implements Injector { @Override public void injectMembers(Object instance) { - + context.getAutowireCapableBeanFactory().autowireBean(instance); } @Override public MembersInjector getMembersInjector(TypeLiteral typeLiteral) { - return null; + return new MembersInjector() { + @Override + public void injectMembers(T instance) { + context.getAutowireCapableBeanFactory().autowireBean(instance); + } + }; } @Override public MembersInjector getMembersInjector(Class type) { - return null; + return getMembersInjector(TypeLiteral.get(type)); } @Override @@ -90,17 +95,36 @@ public class SpringInjector implements Injector { @Override public Provider getProvider(Key key) { - return null; + // 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) { - return null; + if (context.getBeanNamesForType(type).length==0) { + if (injector!=null && injector.getExistingBinding(Key.get(type))!=null) { + return injector.getProvider(type); + } + // TODO: use prototype scope? + context.getDefaultListableBeanFactory().registerBeanDefinition(type.getSimpleName(), new RootBeanDefinition(type)); + } + final Class cls = type; + return new Provider() { + @Override + public T get() { + return context.getBean(cls); + } + }; } @Override public T getInstance(Key key) { - return null; + // TODO: support for other metadata in the key + @SuppressWarnings("unchecked") + T provider = (T) getInstance(key.getTypeLiteral().getRawType()); + return provider; } @Override diff --git a/src/test/java/demo/SpringModule.java b/src/test/java/demo/SpringModule.java new file mode 100644 index 0000000..5f0d455 --- /dev/null +++ b/src/test/java/demo/SpringModule.java @@ -0,0 +1,60 @@ +/* + * 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 demo; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.util.ClassUtils; + +import com.google.inject.Binder; +import com.google.inject.Module; +import com.google.inject.Provider; + +/** + * @author Dave Syer + * + */ +public class SpringModule implements Module { + + private GenericApplicationContext context; + + public SpringModule(GenericApplicationContext context) { + this.context = context; + } + + @Override + public void configure(Binder binder) { + for (String name : context.getBeanDefinitionNames()) { + BeanDefinition definition = context.getBeanDefinition(name); + if (definition.isAutowireCandidate() && definition.getRole() == AbstractBeanDefinition.ROLE_APPLICATION) { + Class type = context.getType(name); + @SuppressWarnings("unchecked") + final Class cls = (Class) type; + Provider provider = new Provider() { + @Override + public Object get() { + return context.getBean(cls); + } + }; + for (Class iface : ClassUtils.getAllInterfacesForClass(cls)) { + @SuppressWarnings("unchecked") + Class unchecked = (Class) iface; + binder.bind(unchecked).toProvider(provider); + } + } + } + } + +} diff --git a/src/test/java/demo/SpringModuleWiringTests.java b/src/test/java/demo/SpringModuleWiringTests.java new file mode 100644 index 0000000..e8e337e --- /dev/null +++ b/src/test/java/demo/SpringModuleWiringTests.java @@ -0,0 +1,45 @@ +/* + * 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 demo; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * @author Dave Syer + * + */ +public class SpringModuleWiringTests extends AbstractCompleteWiringTests { + + @Override + protected Injector createInjector() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + context.register(TestConfig.class); + context.refresh(); + return Guice.createInjector(new SpringModule(context)); + } + + @Configuration + public static class TestConfig { + @Bean + public Service service() { + return new MyService(); + } + } + +}