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

Support SpringDI List injection with @Inject #31826

Merged
merged 1 commit into from
Mar 14, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/spring-di.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ The following table shows how Spring DI annotations can be converted to CDI and

|@Autowired
|@Inject
|
|If the type is `java.util.List`, the `io.quarkus.arc.All` qualifier is added.

|@Qualifier
|@Named
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,10 @@ Set<AnnotationInstance> getAnnotationsToAdd(
Collections.singletonList((AnnotationValue.createStringValue("value", value)))));
}
}

// in Spring List<SomeBean> means that all instances of SomeBean should be injected
if (fieldInfo.type().name().equals(DotNames.LIST)) {
annotationsToAdd.add(create(
QUARKUS_ALL_ANNOTATION,
target,
Collections.emptyList()));
}
addAllAnnotationOnListField(target, annotationsToAdd, fieldInfo);
} else if (fieldInfo.hasAnnotation(CDI_INJECT_ANNOTATION)) {
// Mix case of JSR-303 support in Spring
addAllAnnotationOnListField(target, annotationsToAdd, fieldInfo);
} else if (fieldInfo.hasAnnotation(SPRING_VALUE_ANNOTATION)) {
final AnnotationInstance annotation = fieldInfo.annotation(SPRING_VALUE_ANNOTATION);
addSpringValueAnnotations(target, annotation, true, annotationsToAdd);
Expand Down Expand Up @@ -437,18 +433,11 @@ Set<AnnotationInstance> getAnnotationsToAdd(
CDI_INJECT_ANNOTATION,
target,
Collections.emptyList()));
// in Spring List<SomeBean> means that all instances of SomeBean should be injected
List<Type> parameters = methodInfo.parameterTypes();
for (int i = 0; i < parameters.size(); i++) {
Type parameter = parameters.get(i);
if (parameter.name().equals(DotNames.LIST)) {
annotationsToAdd.add(create(
QUARKUS_ALL_ANNOTATION,
MethodParameterInfo.create(methodInfo, (short) i),
Collections.emptyList()));
}
}
addAllAnnotationOnMethodListParameters(annotationsToAdd, methodInfo);

} else if (methodInfo.hasAnnotation(CDI_INJECT_ANNOTATION)) {
// Mix case of JSR-303 support in Spring
addAllAnnotationOnMethodListParameters(annotationsToAdd, methodInfo);
}

// add method parameter conversion annotations
Expand All @@ -473,6 +462,31 @@ Set<AnnotationInstance> getAnnotationsToAdd(
return annotationsToAdd;
}

private void addAllAnnotationOnListField(AnnotationTarget target, Set<AnnotationInstance> annotationsToAdd,
FieldInfo fieldInfo) {
// in Spring List<SomeBean> means that all instances of SomeBean should be injected
if (fieldInfo.type().name().equals(DotNames.LIST)) {
annotationsToAdd.add(create(
QUARKUS_ALL_ANNOTATION,
target,
Collections.emptyList()));
}
}

private void addAllAnnotationOnMethodListParameters(Set<AnnotationInstance> annotationsToAdd, MethodInfo methodInfo) {
// in Spring List<SomeBean> means that all instances of SomeBean should be injected
List<Type> parameters = methodInfo.parameterTypes();
for (int i = 0; i < parameters.size(); i++) {
Type parameter = parameters.get(i);
if (parameter.name().equals(DotNames.LIST)) {
annotationsToAdd.add(create(
QUARKUS_ALL_ANNOTATION,
MethodParameterInfo.create(methodInfo, (short) i),
Collections.emptyList()));
}
}
}

/**
* Meant to be called with instances of @Component, @Service, @Repository
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,22 @@ public class ListOfBeansTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(Foo.class, ServiceAlpha.class, ServiceBravo.class, Service.class,
.addClasses(Foo.class, Bar.class, ServiceAlpha.class, ServiceBravo.class, Service.class,
Converter.class, ConverterAlpha.class, ConverterBravo.class));

@Inject
Foo foo;

@Inject
Bar bar;

@Test
public void testInjection() {
assertThat(foo.services).hasSize(2).extractingResultOf("ping").containsExactlyInAnyOrder("alpha", "bravo");
assertThat(foo.converters).hasSize(2).extractingResultOf("pong").containsExactlyInAnyOrder("alpha", "bravo");

assertThat(bar.services).hasSize(2).extractingResultOf("ping").containsExactlyInAnyOrder("alpha", "bravo");
assertThat(bar.converters).hasSize(2).extractingResultOf("pong").containsExactlyInAnyOrder("alpha", "bravo");
}

@org.springframework.stereotype.Service
Expand All @@ -43,6 +49,23 @@ public static class Foo {
Foo(List<Converter> converters) {
this.converters = converters;
}
}

/**
* Test Spring with JSR-303 support
*/
@org.springframework.stereotype.Service
public static class Bar {

@Inject
List<Service> services;

final List<Converter> converters;

@Inject
Bar(List<Converter> converters) {
this.converters = converters;
}

}

Expand Down