Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: apply injection point qualifier on BeanProvider's get call #7255

Merged
merged 1 commit into from May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -231,30 +231,93 @@ class BeanOneTwo implements BeanNumber { }
@jakarta.inject.Singleton
class Test {
public BeanProvider<BeanNumber> provider;
Test(@OneQualifier BeanProvider<BeanNumber> provider) {
public BeanProvider<BeanNumber> providerTwo;
Test(@OneQualifier BeanProvider<BeanNumber> provider, @TwoQualifier BeanProvider<BeanNumber> 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()
Paullo612 marked this conversation as resolved.
Show resolved Hide resolved
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<BeanNumber> provider;
public BeanProvider<BeanNumber> providerTwo;
Test(@OneQualifier BeanProvider<BeanNumber> provider, @TwoQualifier BeanProvider<BeanNumber> 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'
}
}
Expand Up @@ -64,23 +64,25 @@ protected BeanProvider<Object> buildProvider(
private final Qualifier<Object> finalQualifier =
qualifier instanceof AnyQualifier ? null : qualifier;

private Qualifier<Object> qualify(Qualifier<Object> 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);
}

@Override
public Optional<Object> find(Qualifier<Object> qualifier) {
Qualifier<Object> 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
Expand All @@ -90,7 +92,7 @@ public BeanDefinition<Object> getDefinition() {

@Override
public Object get(Qualifier<Object> qualifier) {
return ((DefaultBeanContext) context).getBean(resolutionContext, argument, qualifier);
return ((DefaultBeanContext) context).getBean(resolutionContext, argument, qualify(qualifier));
}

@Override
Expand Down