How is @ConfigurationProperties-annotated classes detected automatically with @SpringBootApplication Annotation

…衆ロ難τιáo~ 提交于 2021-02-08 11:36:02

问题


I am learning Spring Boot and have a question with one example in the reference documentation. Following section of the documentation mentions

6. Using the @SpringBootApplication Annotation

A single @SpringBootApplication annotation can be used to enable those three features, that is:

@EnableAutoConfiguration: enable Spring Boot’s auto-configuration mechanism

@ComponentScan: enable @Component scan on the package where the application is located (see the best practices)

@Configuration: allow to register extra beans in the context or import additional configuration classes

and the following example to replace this single annotation by any of the features that it enables is bit confusing for me . The example

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
public class Application {

    public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
    }

}

Explanation for the example

In this example, Application is just like any other Spring Boot application except that @Component-annotated classes and @ConfigurationProperties-annotated classes are not detected automatically and the user-defined beans are imported explicitly (see @Import).

The only major difference I see in the example code above is that it does not have @ComponentScan annotation. I also read in the comments section of an SO answer (Stephane Nicoll May 5 '17 at 11:07) that @Component annotation is not recommended officially to auto detect @ConfigurationProperties. So my assumption is that Spring framework classes with @ConfigurationProperties are not annotated with @Component.

Also I checked the @SpringBootApplication annotation source and couldn't identify anything that should enable the automatic detection of @ConfigurationProperties annotated classes.

The reference document 2.8.3. Enabling @ConfigurationProperties-annotated types section shows the following way to scan and autodetect @ConfigurationProperties

@SpringBootApplication
@ConfigurationPropertiesScan({ "com.example.app", "org.acme.another" })
public class MyApplication {
}

With all these details , I would like to understand

Why is it explicitly mentioned for this example that @ConfigurationProperties-annotated classes are not detected automatically ? and How is @ConfigurationProperties annotated classes automatically detected when @SpringBootApplication is used.

Additional note : I saw a small difference between the prior version of the documentation and the current one. The following reference is missing the current one

Keep in mind that the @EnableConfigurationProperties annotation is also automatically applied to your project so that any existing bean annotated with @ConfigurationProperties is configured from the Environment


回答1:


Following is what I understand from my analysis.

@ConfigurationProperties annotated types can be registered to the ApplicationContext by

  1. Annotating the class with @ConfigurationProperties with an annotation that falls in the scope of @ComponentScan ( @Component, @Service and the like ) . Not recommended as per the comment from Stephane Nicoll , which makes sense to me now.

  2. Using annotation @EnableConfigurationProperties . For this to work the class annotated with @EnableConfigurationProperties should be annotated with an annotation that falls in the scope of @ComponentScan ( @Component, @Service and the like )

  3. Using annotation @ConfigurationPropertiesScan and by making sure the classes annotated with @ConfigurationProperties is placed under its radar. The usage is similar to @ComponentScan .

Now , when we replace @SpringBootApplication with individual annotations that it enables and omit @ComponentScan (as in example) , the @EnableConfigurationProperties way (Point 2) of registering the types with @ConfigurationProperties will not work. This probably answers both my questions on why and how .

This was explicitly mentioned probably because the connection between @EnableConfigurationProperties and @ComponentScan is not that obvious for people like me.

Additional details.

The registration of @ConfigurationProperties annotated types when we use @EnableConfigurationProperties happens through of the EnableConfigurationPropertiesRegistrar class that is imported by the annotation

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesRegistrar.class)
public @interface EnableConfigurationProperties {..}


来源:https://stackoverflow.com/questions/59674619/how-is-configurationproperties-annotated-classes-detected-automatically-with-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!