The @SpringBootApplication annotation on the SpringBoot Boot class is
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
A compound of three annotations. The @SpringBootConfiguration annotation is actually a combination of @Configuration annotation and @Configuration annotation, which has the same function as @Configuration annotation. @ComponentScan This annotation is to mark the package that needs to be scanned. Today I’ll focus on the @enableAutoConfiguration annotation.
The @enableAutoConfiguration annotation is also a product of the @enable * annotation. In short, the @import annotation is used to collect and register Bean definitions for specific scenarios: @enableAspectJAutoProxy dynamically registers beans with the SpringIoc container via @import annotations, @enableAutoConfiguration uses @import to load all qualified beans into the SpringIoc container.
See the @enable * and @import annotations for Spring Boot automatic configuration in the previous article
1. @enableAutoConfiguration is also a composite annotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude()default {};
String[] excludeName() default {};
}
Copy the code
One of the most important is @ Import annotations (AutoConfigurationImportSelector. Class). Using AutoConfigurationImportSelector, @ EnableAutoConfiguration help Spring Boot applications will all eligible @ Configuration Configuration is loaded into the current in the IoC container. The main one is a utility class with the help of Spring Framework 1: The SpringFactoriesLoader loads the meta-INF /spring.factories configuration file. The spring.factories file is a typical properties configuration file, and the configuration format is still Key = Value. Key and Value are full Java class names. Such as: org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.jpa.repository.suppor t.JpaRepositoryFactory
2, AutoConfigurationImportSelector source code
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if(! isEnabled(annotationMetadata)) {return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader); / / 1
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata); / / 2
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
Copy the code
- 1. Get the annotation information
- 2. Obtain the configuration list
Source code. Including AutoConfigurationMetadataLoader loadMetadata method
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, PATH);
}
static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
try{ Enumeration<URL> urls = (classLoader ! =null)? classLoader.getResources(path) : ClassLoader.getSystemResources(path); Properties properties =new Properties();
while (urls.hasMoreElements()) {
properties.putAll(PropertiesLoaderUtils
.loadProperties(new UrlResource(urls.nextElement())));
}
return loadMetadata(properties);
}
catch (IOException ex) {
throw new IllegalArgumentException(
"Unable to load @ConditionalOnClass location [" + path + "]", ex); }}Copy the code
GetAutoConfigurationEntry method:
protected AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
if(! isEnabled(annotationMetadata)) {return EMPTY_ENTRY;
}
/ / 1.
AnnotationAttributes attributes = getAttributes(annotationMetadata);
/ / 2.
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
/ / 3.
configurations = removeDuplicates(configurations);
/ / 4.
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
/ / 5.
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
Copy the code
- 1. Get all the attribute information on the annotation
- 2. Get the candidate configuration list [Core steps]
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; } Copy the code
Through SpringFactoriesLoader loadFactoryNames for configuration information
- 3. To heavy
- 4. Configure the exclude information to exclude unnecessary information
- 5. Send events