SpringBoot自动配置原理

129 阅读2分钟

SpringBoot源码入口

@SpringBootApplication

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
  1. @SpringBootConfiguration
  • 1.1 SpringBoot配置类,表示这是一个SpringBoot的配置类
  1. @EnableAutoConfiguration
  • 2.1. SpringBoot开启自动配置,自动加载自动配置类
  1. TypeExcludeFilter
  • 3.1. springBoot对外提供的扩展类,可以公我们去按照我们的方式进行排除
  1. AutoConfigurationExcludeFilter
  • 4.1. 排除所以配置类并且自动配置类中的其中一个

@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
  1. @AutoConfigurationPackage
1.1  将当前配置类所在包保存在BasePackages的Bean中,供Spring内部使用
  1. @Import ( AutoConfigurationImportSelector.class )
2.1.  EnableAutoConfiguration使用Import来导入配置

AutoConfigurationImportSelector

  1. 继承DeferredImportSelector接口
  2. getAutoConfigurationEntry方法

2.1. 扫描具有META-INF/spring.factories包中

	protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 从META-INF/spring.factories中获得候选的自动配置类
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		// 排重
        configurations = removeDuplicates(configurations);
		// 根据EnableAutoCongiguration注解中属性,获取不需要自动装配的类名单
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        // 根据EnableAutoConfiguration注解中属性,获取不需要自动装配的类名单
        // @EnableAutoConfiguration.exclude
        // spring.autoconfigure.exclude 进行排除
		checkExcludedClasses(configurations, exclusions);
        // exclusions也排除
		configurations.removeAll(exclusions);
        // 通过读取spring.factories中的OnBeanCondition/OnClassCondition/OnWebApplicationCondition进行过滤
		configurations = getConfigurationClassFilter().filter(configurations);
        // 这个方法是调用实现了AutoConfigurationImportListener 的bean.. 分别把候选的配置名单,和排除的配置名单传 进去做扩展
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

@Import

读取spring.factories文件就在该包下面的KV值。如Filter,监听器等。

org.springframework.boot.autoconfigure.EnableAutoConfiguration是自动配置包

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
xxx,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

然后通过org.springframework.context.annotation.ImportSelector#selectImports方法,找到JavaConfig自动配置类的全限定类名加载对应的class,然后就所有的自动配置类加载到Spring容器中

注解的作用

@Configuration(proxyBeanMethods = false)

标记@Configuration Spring底层会给配置cglib动态代理

防止每次调用本类的Bean方法而重新创建对象,Bean是默认单例的

@EnableConfigurationProperties(ServerProperties.class)

  1. 启动可以在配置类设置的属性 对应的类
  2. @xxxConditional根据当前不同的条件判断,决定这个配置类是否生效?

另外附上 Springboot中所有扫描类