Skip to content

findAnnotationOnBean finds annotations from a static @Bean method's enclosing class #28298

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

Closed
wilkinsona opened this issue Apr 7, 2022 · 2 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@wilkinsona
Copy link
Member

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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 7, 2022
@sbrannen sbrannen changed the title findAnnotationOnBean finds annotations from a static @Bean method's @Configuration class findAnnotationOnBean finds annotations from a static @Bean method's enclosing class Apr 7, 2022
@sbrannen sbrannen added type: bug A general bug in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Apr 7, 2022
@sbrannen sbrannen modified the milestones: 6.0.0-M4, 6.0.0-M5 Apr 7, 2022
wilkinsona pushed a commit to spring-projects/spring-boot that referenced this issue Apr 7, 2022
This works around spring-projects/spring-framework#28298. The bug
means that when a @configuration class is annotated with
@ConfigurationProperties any bean defined by a static @bean method
is considered to be annotated with @ConfigurationProperties.

See gh-30068
@284831721
Copy link

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
	 */

@wilkinsona
Copy link
Member Author

Both should pass. The tests are illustrating the described difference between static and instance bean methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants