问题
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
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.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 )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