diff --git a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java index 8c8501c..be30427 100644 --- a/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java +++ b/src/main/java/org/springframework/guice/annotation/ModuleRegistryConfiguration.java @@ -55,6 +55,7 @@ import org.springframework.context.ApplicationContextException; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import org.springframework.guice.module.SpringModule; @@ -140,9 +141,10 @@ class ModuleRegistryConfiguration bean.setResourceDescription(SpringModule.SPRING_GUICE_SOURCE); } bean.setAttribute(SpringModule.SPRING_GUICE_SOURCE, true); - if (key.getAnnotation() != null) { + if (key.getAnnotationType() != null) { bean.addQualifier(new AutowireCandidateQualifier(Qualifier.class, - getValueAttributeForNamed(key.getAnnotation()))); + getValueAttributeForNamed(key))); + bean.addQualifier(new AutowireCandidateQualifier(key.getAnnotationType(), getValueAttributeForNamed(key))); } registry.registerBeanDefinition(extractName(key), bean); } @@ -151,7 +153,7 @@ class ModuleRegistryConfiguration private String extractName(Key key) { final String className = key.getTypeLiteral().getType().getTypeName(); - String valueAttribute = getValueAttributeForNamed(key.getAnnotation()); + String valueAttribute = getValueAttributeForNamed(key); if (valueAttribute != null) { return valueAttribute + "_" + className; } @@ -160,12 +162,15 @@ class ModuleRegistryConfiguration } } - private String getValueAttributeForNamed(Annotation annotation) { - if (annotation instanceof Named) { - return ((Named) annotation).value(); + private String getValueAttributeForNamed(Key key) { + if (key.getAnnotation() instanceof Named) { + return ((Named) key.getAnnotation()).value(); } - else if (annotation instanceof javax.inject.Named) { - return ((javax.inject.Named) annotation).value(); + else if (key.getAnnotation() instanceof javax.inject.Named) { + return ((javax.inject.Named) key.getAnnotation()).value(); + } + else if (key.getAnnotationType() != null){ + return key.getAnnotationType().getName(); } else { return null; diff --git a/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java b/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java index c29e7cb..e8e7361 100644 --- a/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java +++ b/src/main/java/org/springframework/guice/module/GuiceAutowireCandidateResolver.java @@ -15,8 +15,11 @@ */ package org.springframework.guice.module; +import com.google.inject.BindingAnnotation; import com.google.inject.Injector; import com.google.inject.Key; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -40,9 +43,11 @@ import java.util.Map; class GuiceAutowireCandidateResolver extends ContextAnnotationAutowireCandidateResolver { private Provider injectorProvider; + private final Log logger = LogFactory.getLog(getClass()); public GuiceAutowireCandidateResolver(Provider injectorProvider) { this.injectorProvider = injectorProvider; + addQualifierType(BindingAnnotation.class); } @Override @@ -102,13 +107,18 @@ class GuiceAutowireCandidateResolver extends ContextAnnotationAutowireCandidateR public void releaseTarget(Object target) { } }; - ProxyFactory pf = new ProxyFactory(); - pf.setTargetSource(ts); - Class dependencyType = descriptor.getDependencyType(); - if (dependencyType.isInterface()) { - pf.addInterface(dependencyType); + try { + ProxyFactory pf = new ProxyFactory(); + pf.setTargetSource(ts); + Class dependencyType = descriptor.getDependencyType(); + if (dependencyType.isInterface()) { + pf.addInterface(dependencyType); + } + return pf.getProxy(beanFactory.getBeanClassLoader()); + } catch(Exception e) { + logger.debug("Failed to build lazy resolution proxy to Guice", e); } - return pf.getProxy(beanFactory.getBeanClassLoader()); + return null; } private boolean isCollectionType(Class type) { diff --git a/src/test/java/org/springframework/guice/BindingAnnotationTests.java b/src/test/java/org/springframework/guice/BindingAnnotationTests.java index 0d3e28c..3a5e431 100644 --- a/src/test/java/org/springframework/guice/BindingAnnotationTests.java +++ b/src/test/java/org/springframework/guice/BindingAnnotationTests.java @@ -1,5 +1,6 @@ package org.springframework.guice; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.lang.annotation.ElementType; @@ -10,7 +11,9 @@ import java.lang.annotation.Target; import javax.inject.Named; import javax.inject.Qualifier; +import com.google.inject.AbstractModule; 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; @@ -41,17 +44,19 @@ public class BindingAnnotationTests { SomeDependencyWithQualifierOnProvider someDependencyWithQualifierOnClass = injector.getInstance(Key.get(SomeDependencyWithQualifierOnProvider.class, SomeQualifierAnnotation.class)); assertNotNull(someDependencyWithQualifierOnClass); - //Check @BindingAnnotaiton + //Check @BindingAnnotation on Spring @Bean available in Guice SomeDependencyWithQualifierOnProvider someDependencyWithBindingAnnotationOnProvider = injector.getInstance(Key.get(SomeDependencyWithQualifierOnProvider.class, SomeQualifierAnnotation.class)); assertNotNull(someDependencyWithBindingAnnotationOnProvider); - + + //Check @BindingAnnotation on Guice Binding available in Spring + SomeStringHolder stringHolder = context.getBean(SomeStringHolder.class); + assertEquals("annotated", stringHolder.annotatedString); + assertEquals("other", stringHolder.otherAnnotatedString); + //Check javax @Named SomeDependencyWithNamedAnnotationOnProvider someDependencyWithNamedAnnotationOnProvider = injector.getInstance(Key.get(SomeDependencyWithNamedAnnotationOnProvider.class, Names.named("javaxNamed"))); assertNotNull(someDependencyWithNamedAnnotationOnProvider); - - SomeDependencyWithNamedAnnotationOnProvider someSecondDependencyWithNamedAnnotationOnProvider = injector.getInstance(Key.get(SomeDependencyWithNamedAnnotationOnProvider.class, Names.named("javaxNamed2"))); - assertNotNull(someSecondDependencyWithNamedAnnotationOnProvider); - + //Check Guice @Named SomeDependencyWithGuiceNamedAnnotationOnProvider someDependencyWithGuiceNamedAnnotationOnProvider = injector.getInstance(Key.get(SomeDependencyWithGuiceNamedAnnotationOnProvider.class, Names.named("guiceNamed"))); assertNotNull(someDependencyWithGuiceNamedAnnotationOnProvider); @@ -77,10 +82,10 @@ public class BindingAnnotationTests { public static class SomeDependencyWithBindingAnnotationOnProvider {} public static class SomeDependencyWithNamedAnnotationOnProvider {} public static class SomeDependencyWithGuiceNamedAnnotationOnProvider {} - public static interface SomeInterface{} + public interface SomeInterface{} public static class SomeDependencyWithQualifierOnProviderWhichImplementsSomeInterface implements SomeInterface {} public static class SomeNamedDepWithType1 {} - public static class SomeNamedDepWithType2 {} + public static class SomeNamedDepWithType2 {} } @Qualifier @@ -89,10 +94,27 @@ public class BindingAnnotationTests { @interface SomeQualifierAnnotation {} @BindingAnnotation -@Target({ElementType.TYPE, ElementType.METHOD}) +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @interface SomeBindingAnnotation {} +@BindingAnnotation +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@interface SomeOtherBindingAnnotation {} + +class SomeStringHolder { + + + @Autowired + @SomeBindingAnnotation + public String annotatedString; + + @Autowired + @SomeOtherBindingAnnotation + String otherAnnotatedString; + +} @EnableGuiceModules @Configuration @@ -151,4 +173,20 @@ class BindingAnnotationTestsConfig { public SomeNamedDepWithType2 someNamedDepWithType2() { return new SomeNamedDepWithType2(); } + + @Bean + public SomeStringHolder stringHolder() { + return new SomeStringHolder(); + } + + @Bean + public AbstractModule module() { + return new AbstractModule() { + @Override + protected void configure() { + bind(String.class).annotatedWith(SomeBindingAnnotation.class).toInstance("annotated"); + bind(String.class).annotatedWith(SomeOtherBindingAnnotation.class).toInstance("other"); + } + }; + } } \ No newline at end of file