diff --git a/inject-java/src/test/groovy/io/micronaut/inject/provider/BeanProviderSpec.groovy b/inject-java/src/test/groovy/io/micronaut/inject/provider/BeanProviderSpec.groovy index fc562dd1de6..babe938f5d1 100644 --- a/inject-java/src/test/groovy/io/micronaut/inject/provider/BeanProviderSpec.groovy +++ b/inject-java/src/test/groovy/io/micronaut/inject/provider/BeanProviderSpec.groovy @@ -231,30 +231,93 @@ class BeanOneTwo implements BeanNumber { } @jakarta.inject.Singleton class Test { public BeanProvider provider; - Test(@OneQualifier BeanProvider provider) { + public BeanProvider providerTwo; + Test(@OneQualifier BeanProvider provider, @TwoQualifier BeanProvider providerTwo) { this.provider = provider; + this.providerTwo = providerTwo; } } ''') - when: + when: 'retrieve test bean' def bean = getBean(context, 'test.Test') - then: + then: 'providerTwo successfully finds BeanOneTwo because of injection point qualifier' bean.provider.isPresent() + bean.providerTwo.find(null).get().class.name == 'test.BeanOneTwo' - when: + when: 'attempt to find bean through provider with null qualifier as argument' bean.provider.find(null) - then: + then: 'NonUniqueBeanException is thrown, as both BeanOne and BeanOneTwo are qualified by @OneQualifier' thrown(NonUniqueBeanException) - when: + when: 'attempt to find bean through provider with @TwoQualifier as argument' def metadata = new MutableAnnotationMetadata() metadata.addDeclaredAnnotation('test.TwoQualifier', Collections.emptyMap()) def foundBean = bean.provider.find(Qualifiers.byAnnotation(metadata, 'test.TwoQualifier')) - then: + then: 'BeanOneTwo is found' foundBean.isPresent() foundBean.get().class.name == 'test.BeanOneTwo' } + + void "test BeanProvider's get by qualifier method" () { + given: + ApplicationContext context = buildContext('''\ +package test; + +import io.micronaut.inject.annotation.*; +import io.micronaut.context.annotation.*; +import io.micronaut.context.BeanProvider; + +@jakarta.inject.Qualifier +@java.lang.annotation.Documented +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@interface OneQualifier { } + +@jakarta.inject.Qualifier +@java.lang.annotation.Documented +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@interface TwoQualifier { } + +interface BeanNumber { } + +@OneQualifier +class BeanOne implements BeanNumber { } + +@OneQualifier +@TwoQualifier +class BeanOneTwo implements BeanNumber { } + +@jakarta.inject.Singleton +class Test { + public BeanProvider provider; + public BeanProvider providerTwo; + Test(@OneQualifier BeanProvider provider, @TwoQualifier BeanProvider providerTwo) { + this.provider = provider; + this.providerTwo = providerTwo; + } +} +''') + when: 'retrieve test bean' + def bean = getBean(context, 'test.Test') + + then: 'providerTwo successfully gets BeanOneTwo because of injection point qualifier' + bean.provider.isPresent() + bean.providerTwo.get(null).class.name == 'test.BeanOneTwo' + + when: 'attempt to get bean through provider with null qualifier as argument' + bean.provider.get(null) + + then: 'NonUniqueBeanException is thrown, as both BeanOne and BeanOneTwo are qualified by @OneQualifier' + thrown(NonUniqueBeanException) + + when: 'attempt to get bean through provider with @TwoQualifier as argument' + def metadata = new MutableAnnotationMetadata() + metadata.addDeclaredAnnotation('test.TwoQualifier', Collections.emptyMap()) + def foundBean = bean.provider.get(Qualifiers.byAnnotation(metadata, 'test.TwoQualifier')) + + then: 'BeanOneTwo is returned' + foundBean.class.name == 'test.BeanOneTwo' + } } diff --git a/inject/src/main/java/io/micronaut/inject/provider/BeanProviderDefinition.java b/inject/src/main/java/io/micronaut/inject/provider/BeanProviderDefinition.java index 5036ddd76ba..a92a1c55c5f 100644 --- a/inject/src/main/java/io/micronaut/inject/provider/BeanProviderDefinition.java +++ b/inject/src/main/java/io/micronaut/inject/provider/BeanProviderDefinition.java @@ -64,6 +64,17 @@ protected BeanProvider buildProvider( private final Qualifier finalQualifier = qualifier instanceof AnyQualifier ? null : qualifier; + private Qualifier qualify(Qualifier qualifier) { + if (finalQualifier == null) { + return qualifier; + } else if (qualifier == null) { + return finalQualifier; + } + + //noinspection unchecked + return Qualifiers.byQualifiers(finalQualifier, qualifier); + } + @Override public Object get() { return ((DefaultBeanContext) context).getBean(resolutionContext, argument, finalQualifier); @@ -71,16 +82,7 @@ public Object get() { @Override public Optional find(Qualifier qualifier) { - Qualifier actualQualifier; - if (finalQualifier == null) { - actualQualifier = qualifier; - } else if (qualifier == null) { - actualQualifier = finalQualifier; - } else { - actualQualifier = Qualifiers.byQualifiers(finalQualifier, qualifier); - } - - return ((DefaultBeanContext) context).findBean(resolutionContext, argument, actualQualifier); + return ((DefaultBeanContext) context).findBean(resolutionContext, argument, qualify(qualifier)); } @Override @@ -90,7 +92,7 @@ public BeanDefinition getDefinition() { @Override public Object get(Qualifier qualifier) { - return ((DefaultBeanContext) context).getBean(resolutionContext, argument, qualifier); + return ((DefaultBeanContext) context).getBean(resolutionContext, argument, qualify(qualifier)); } @Override