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