0
点赞
收藏
分享

微信扫一扫

Spring Boot自动配置原理


首先我们看下Spring Boot Starter的Maven依赖,在图中不用想我们就可以才出来自动配置一定主要是由​​spring-boot-autoconfigure​​​模快来实现的,由此,我们着重研究​​spring-boot-autoconfigure​​的原理就可以推断出Spring Boot的自动配置原理,Start!

Spring Boot自动配置原理_spring

​@SpringBootApplication​​注解依赖图

Spring Boot自动配置原理_类名_02

1 开启自动配置

开启自动配置主要是由​​@EnableAutoConfiguration​​注解来实现的

翻下源码:

@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 {};

}

很容易我们发现在这里它导入了一个​​AutoConfigurationImportSelector​​的类,点进去看下

他有几个很重要的方法,粘贴下:

/**
* 判断是否开启自动配置,直接返回true
*/
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass() == AutoConfigurationImportSelector.class) {
return getEnvironment().getProperty(
EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,
true);
}
return true;
}

/**
* 返回应该考虑的自动配置类名. 默认情况下该方法将使用 {@link SpringFactoriesLoader}
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
// 这一步非常重要,加载Spring Boot自动配置的核心文件
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;
}

/**
* 检查排除的自动配置类
*/
private void checkExcludedClasses(List<String> configurations,
Set<String> exclusions) {
List<String> invalidExcludes = new ArrayList<>(exclusions.size());
for (String exclusion : exclusions) {
if (ClassUtils.isPresent(exclusion, getClass().getClassLoader())
&& !configurations.contains(exclusion)) {
invalidExcludes.add(exclusion);
}
}
if (!invalidExcludes.isEmpty()) {
handleInvalidExcludes(invalidExcludes);
}
}

我们顺藤摸瓜,看下​​SpringFactoriesLoader​​类

public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap();
}

直接看到了加载的核心配置文件​​META-INF/spring.factories​​,然后其他两个属性分别是日志和缓存的声明

我们再简单的看下​​spring.factories​​文件

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

......

发现声明了好多配置项和自动配置类,这足以说明自动配置并没有多么高大上,只是Spring团队的开发者们一步一步用各种方式实现的,致敬!

2 条件注解

Spring Boot自动配置原理_spring boot_03

Conditional翻译为‘有条件的’

我们挑几个重要的来讲:

  • @Conditional:按照一定的条件进行判断,满足条件给容器注册bean
  • @ConditionalOnClass:按照有无该类条件进行判断,满足条件给容器注册bean
  • @ConditionalOnBean:按照有无该Bean条件进行判断,满足条件给容器注册bean
  • @ConditionalOnMissingBean:按照有无该Bean条件进行判断,满足条件给容器注册bean
  • @ConditionalOnProperty:按照有无该Property条件进行判断,满足条件给容器注册bean

3 启动配置流程总结

Spring Boot自动配置原理_ide_04

4 总体流程图

Spring Boot自动配置原理_ide_05



举报

相关推荐

0 条评论