Affects: 5.3.x
When a bean is defined using a static method, findAnnotationOnBean
finds an annotation from the @Configuration
class to which the static @Bean
method belongs. The annotation is not found if the @Bean
method is not static.
The following tests illustrate this behavior:
package com.example;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
class FindAnnotationOnBeanTests {
@Test
void beanDefinedInInstanceMethodDoesNotHaveAnnotationsFromItsConfigurationClass() {
beanDoesNotHaveAnnotationsFromItsConfigurationClass(InstanceBeanMethodConfiguration.class);
}
@Test
void beanDefinedInStaticMethodDoesNotHaveAnnotationsFromItsConfigurationClass() {
beanDoesNotHaveAnnotationsFromItsConfigurationClass(StaticBeanMethodConfiguration.class);
}
void beanDoesNotHaveAnnotationsFromItsConfigurationClass(Class<?> config) {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(config)) {
ExampleAnnotation annotation = context.getBeanFactory().findAnnotationOnBean("exampleBean",
ExampleAnnotation.class);
assertThat(annotation).isNull();
}
}
@Configuration
@ExampleAnnotation
static class StaticBeanMethodConfiguration {
@Bean
static String exampleBean() {
return "example";
}
}
@Configuration
@ExampleAnnotation
static class InstanceBeanMethodConfiguration {
@Bean
String exampleBean() {
return "example";
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
static @interface ExampleAnnotation {
}
}
beanDefinedInInstanceMethodDoesNotHaveAnnotationsFromItsConfigurationClass
passes but beanDefinedInStaticMethodDoesNotHaveAnnotationsFromItsConfigurationClass
fails.
Comment From: 284831721
I can't understand, so, which test result is expected? first or second.
From the findAnnotationOnBean
method's comment describe as follow, I think test 1 is the expected behavior, am I right?
/**
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
* traversing its interfaces and super classes if no annotation can be found on
* the given class itself, as well as checking the bean's factory method (if any).
* @param beanName the name of the bean to look for annotations on
* @param annotationType the type of annotation to look for
* (at class, interface or factory method level of the specified bean)
* @return the annotation of the given type if found, or {@code null} otherwise
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 3.0
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
*/
Comment From: wilkinsona
Both should pass. The tests are illustrating the described difference between static and instance bean methods.