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.springframeworkspring-framework-bom
- 4.2.5.RELEASE
+ ${spring.version}pomimport
@@ -50,6 +50,7 @@
1.6UTF-8UTF-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 super T> 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