Skip to content

Commit 5f8c01c

Browse files
authored
Improvements to bean context qualifiers (#12053)
1 parent e79318e commit 5f8c01c

31 files changed

+358
-183
lines changed

http/src/main/java/io/micronaut/http/body/DefaultMessageBodyHandlerRegistry.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.micronaut.http.codec.CodecConfiguration;
2727
import io.micronaut.http.codec.MediaTypeCodec;
2828
import io.micronaut.inject.BeanType;
29+
import io.micronaut.inject.QualifiedBeanType;
2930
import io.micronaut.inject.qualifiers.FilteringQualifier;
3031
import io.micronaut.inject.qualifiers.MatchArgumentQualifier;
3132
import io.micronaut.inject.qualifiers.Qualifiers;
@@ -156,6 +157,11 @@ public <K extends BeanType<T>> Collection<K> filter(Class<T> beanType, Collectio
156157
return all;
157158
}
158159

160+
@Override
161+
public <BT extends QualifiedBeanType<T>> Collection<BT> filterQualified(Class<T> beanType, Collection<BT> candidates) {
162+
return filter(beanType, candidates);
163+
}
164+
159165
private int findOrder(BeanType<?> beanType) {
160166
int order = 0;
161167
String[] applicableTypes = beanType.getAnnotationMetadata().stringValues(annotationType);

inject-java/src/test/groovy/io/micronaut/inject/context/processor/BeanDefinitionProcessorSpec.groovy

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616
package io.micronaut.inject.context.processor
1717

1818
import io.micronaut.context.ApplicationContext
19-
import io.micronaut.context.BeanContext
2019
import spock.lang.Specification
2120

2221
class BeanDefinitionProcessorSpec extends Specification {
2322

2423
void "test bean processors are invoked"() {
2524
given:
26-
ApplicationContext ctx = ApplicationContext.run()
25+
ApplicationContext ctx = ApplicationContext.run(["spec.name": "BeanDefinitionProcessorSpec"])
2726

2827
expect:
2928
ctx.getBean(ProcessedAnnotationProcessor).beans.size() == 1

inject-java/src/test/groovy/io/micronaut/inject/context/processor/ProcessedAnnotationProcessor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
import io.micronaut.context.BeanContext;
1919
import io.micronaut.context.annotation.Context;
20+
import io.micronaut.context.annotation.Requires;
2021
import io.micronaut.context.processor.BeanDefinitionProcessor;
2122
import io.micronaut.inject.BeanDefinition;
2223

2324
import java.util.HashSet;
2425
import java.util.Set;
2526

27+
@Requires(property = "spec.name", value = "BeanDefinitionProcessorSpec")
2628
@Context
2729
public class ProcessedAnnotationProcessor implements BeanDefinitionProcessor<ProcessedAnnotation> {
2830
private Set<BeanDefinition<?>> beans = new HashSet<>();

inject-java/src/test/groovy/io/micronaut/inject/context/processor/SomeBean.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package io.micronaut.inject.context.processor;
1717

18+
import io.micronaut.context.annotation.Requires;
19+
20+
@Requires(property = "spec.name", value = "BeanDefinitionProcessorSpec")
1821
@ProcessedAnnotation
1922
public class SomeBean {
2023
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.micronaut.inject.qualifiers.stereotype;
2+
3+
import io.micronaut.context.annotation.Requires;
4+
import jakarta.inject.Singleton;
5+
6+
@Requires(property = "spec.name", value = "StereotypeQualifierSpec")
7+
@MyStereotype
8+
@Singleton
9+
public class MyBean {
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.micronaut.inject.qualifiers.stereotype;
2+
3+
import io.micronaut.context.annotation.Requires;
4+
import jakarta.inject.Singleton;
5+
6+
@Requires(property = "spec.name", value = "StereotypeQualifierSpec")
7+
@MyRepeatableStereotype
8+
@Singleton
9+
public class MyBean2 {
10+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.micronaut.inject.qualifiers.stereotype;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Repeatable;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
9+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
10+
11+
@Documented
12+
@Retention(RUNTIME)
13+
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
14+
@Repeatable(MyRepeatableStereotype.Container.class)
15+
public @interface MyRepeatableStereotype {
16+
17+
@Documented
18+
@Retention(RUNTIME)
19+
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
20+
@interface Container {
21+
MyRepeatableStereotype[] value();
22+
}
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.micronaut.inject.qualifiers.stereotype;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.Target;
7+
8+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
9+
10+
@Documented
11+
@Retention(RUNTIME)
12+
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
13+
public @interface MyStereotype {
14+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.micronaut.inject.qualifiers.stereotype;
2+
3+
import io.micronaut.context.ApplicationContext;
4+
import io.micronaut.context.Qualifier;
5+
import io.micronaut.inject.qualifiers.Qualifiers;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.util.Map;
9+
10+
import static org.junit.jupiter.api.Assertions.assertEquals;
11+
12+
class StereotypeQualifierTest {
13+
14+
@Test
15+
void testByStereotypeQualifier() {
16+
try (ApplicationContext context = ApplicationContext.run(Map.of("spec.name", "StereotypeQualifierSpec"))) {
17+
Qualifier<Object> qualifier = Qualifiers.byQualifiers(Qualifiers.byStereotype(MyStereotype.class));
18+
var definitions = context.getBeanDefinitions(qualifier);
19+
assertEquals(1, definitions.size());
20+
var beanType = definitions.iterator().next().getBeanType();
21+
assertEquals(MyBean.class, beanType);
22+
}
23+
}
24+
25+
@Test
26+
void testByNamedStereotypeQualifier() {
27+
try (ApplicationContext context = ApplicationContext.run(Map.of("spec.name", "StereotypeQualifierSpec"))) {
28+
Qualifier<Object> qualifier = Qualifiers.byQualifiers(Qualifiers.byStereotype(MyStereotype.class.getName()));
29+
var definitions = context.getBeanDefinitions(qualifier);
30+
assertEquals(1, definitions.size());
31+
var beanType = definitions.iterator().next().getBeanType();
32+
assertEquals(MyBean.class, beanType);
33+
}
34+
}
35+
36+
@Test
37+
void testByRepeatableStereotypeQualifier() {
38+
try (ApplicationContext context = ApplicationContext.run(Map.of("spec.name", "StereotypeQualifierSpec"))) {
39+
Qualifier<Object> qualifier = Qualifiers.byQualifiers(Qualifiers.byStereotype(MyRepeatableStereotype.class));
40+
var definitions = context.getBeanDefinitions(qualifier);
41+
assertEquals(1, definitions.size());
42+
var beanType = definitions.iterator().next().getBeanType();
43+
assertEquals(MyBean2.class, beanType);
44+
}
45+
}
46+
47+
@Test
48+
void testByRepeatableNamedStereotypeQualifier() {
49+
try (ApplicationContext context = ApplicationContext.run(Map.of("spec.name", "StereotypeQualifierSpec"))) {
50+
Qualifier<Object> qualifier = Qualifiers.byQualifiers(Qualifiers.byStereotype(MyRepeatableStereotype.class.getName()));
51+
var definitions = context.getBeanDefinitions(qualifier);
52+
assertEquals(1, definitions.size());
53+
var beanType = definitions.iterator().next().getBeanType();
54+
assertEquals(MyBean2.class, beanType);
55+
}
56+
}
57+
}

inject/src/main/java/io/micronaut/context/AbstractInitializableBeanDefinition.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,19 @@ public int hashCode() {
296296

297297
@Override
298298
public String toString() {
299-
Class<?> declaringType = constructor == null ? type : constructor.declaringType;
300-
return "Definition: " + declaringType.getName();
299+
if (constructor == null) {
300+
return "Definition: " + type.getName();
301+
}
302+
if (constructor.declaringType.equals(type)) {
303+
return "Definition: " + type.getName();
304+
}
305+
if (constructor instanceof MethodReference methodConstructor) {
306+
return "Definition: " + type.getName() + " Factory: " + constructor.declaringType.getName() + "#" + methodConstructor.methodName;
307+
}
308+
if (constructor instanceof FieldReference fieldReference) {
309+
return "Definition: " + type.getName() + " Factory: " + constructor.declaringType.getName() + "." + fieldReference.argument.getName();
310+
}
311+
return "Definition: " + type.getName() + " Factory: " + constructor.declaringType.getName();
301312
}
302313

303314
@Override

0 commit comments

Comments
 (0)