Dont deduce type for OnBean conditions when annotations are specified

Update `OnBeanCondition` to consider the annotations attribute as well
as the types and names when determining if the bean type can be deduced.

Fixes gh-42484
This commit is contained in:
Phillip Webb
2024-10-02 15:19:05 -07:00
parent fc2878a924
commit 90f375ea3e
2 changed files with 46 additions and 2 deletions

View File

@@ -546,7 +546,7 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
this.strategy = annotation.getValue("search", SearchStrategy.class).orElse(null);
Set<String> types = extractTypes(attributes);
BeanTypeDeductionException deductionException = null;
if (types.isEmpty() && this.names.isEmpty()) {
if (types.isEmpty() && this.names.isEmpty() && this.annotations.isEmpty()) {
try {
types = deducedBeanType(context, metadata);
}
@@ -602,7 +602,7 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
}
protected void validate(BeanTypeDeductionException ex) {
if (!hasAtLeastOneElement(this.types, this.names, this.annotations)) {
if (!hasAtLeastOneElement(getTypes(), getNames(), getAnnotations())) {
String message = getAnnotationName() + " did not specify a bean using type, name or annotation";
if (ex == null) {
throw new IllegalStateException(message);

View File

@@ -137,6 +137,14 @@ class ConditionalOnMissingBeanTests {
});
}
@Test // gh-42484
void testAnnotationOnMissingBeanConditionOnMethodWhenNoAnnotatedBeans() {
// There are no beans with @TestAnnotation but there is an UnrelatedExampleBean
this.contextRunner
.withUserConfiguration(UnrelatedExampleBeanConfiguration.class, OnAnnotationMethodConfiguration.class)
.run((context) -> assertThat(context).hasBean("conditional"));
}
@Test
void testOnMissingBeanConditionOutputShouldNotContainConditionalOnBeanClassInMessage() {
this.contextRunner.withUserConfiguration(OnBeanNameConfiguration.class).run((context) -> {
@@ -594,6 +602,17 @@ class ConditionalOnMissingBeanTests {
}
@Configuration(proxyBeanMethods = false)
static class OnAnnotationMethodConfiguration {
@Bean
@ConditionalOnMissingBean(annotation = TestAnnotation.class)
UnrelatedExampleBean conditional() {
return new UnrelatedExampleBean("conditional");
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(annotation = TestAnnotation.class)
static class OnAnnotationWithFactoryBeanConfiguration {
@@ -668,6 +687,16 @@ class ConditionalOnMissingBeanTests {
}
@Configuration(proxyBeanMethods = false)
static class UnrelatedExampleBeanConfiguration {
@Bean
UnrelatedExampleBean unrelatedExampleBean() {
return new UnrelatedExampleBean("test");
}
}
@Configuration(proxyBeanMethods = false)
static class ImpliedOnBeanMethod {
@@ -851,6 +880,21 @@ class ConditionalOnMissingBeanTests {
}
static class UnrelatedExampleBean {
private final String value;
UnrelatedExampleBean(String value) {
this.value = value;
}
@Override
public String toString() {
return this.value;
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented