我们写一个springboot项目的时候通过注解@SpringBootApplication来实现,程序的自动加载及扫描和springboot自身配置加载的
再具体一点:就是通过@SpringBootApplication中的@EableAutoConfiguration注解来实现的,
怎么实现的呢?
我们就需要看看源码,来了解@EableAutoConfiguration的实现原理了
@EnableAutoConfiguration是开启自动配置的注解,在创建的Spring Boot项目中并不能直接看到此注解,它是由组合注解@SpringBootApplication引入的。在Spring Boot入口类(除单元测试外)中,唯一的一个注解就是@SpringBootApplication。它是Spring Boot项目的核心注解,用于开启自动配置,准确说是通过该注解内组合的@EnableAutoConfiguration开启了自动配置。
在未使用Spring Boot的情况下,Bean的生命周期由Spring来管理,然而Spring无法自动配置@Configuration注解的类。而Spring Boot的核心功能之一就是根据约定自动管理该注解标注的类。用来实现该功能的组件之一便是@EnableAutoConfiguration注解。@EnableAutoConfiguration位于spring-boot-autoconfigure包内,当使用@SpringBootApplication注解时,@EnableAutoConfiguration注解会自动生效。@EnableAutoConfiguration的主要功能是启动Spring应用程序上下文时进行自动配置
@EnableAutoConfiguration注解提供了一个常量和两个成员参数的定义。
·ENABLED_OVERRIDE_PROPERTY:用来覆盖开启/关闭自动配置的功能。
·exclude:根据类(Class)排除指定的自动配置。
·excludeName:根据类名排除指定的自动配置。
AutoConfigurationImportSelector是实现自动配置的关键
AutoConfigurationImportSelector源码解析
@EnableAutoConfiguration的关键功能是通过@Import注解导入的ImportSelector来完成的。从源代码得知@Import(AutoConfigurationImportSelector.class)是@EnableAutoConfiguration注解的组成部分,也是自动配置功能的核心实现者。@Import的作用和xml配置中<import/>标签的作用一样,我们可以通过@Import引入@Configuration注解的类,也可以导入实现了ImportSelector或ImportBeanDefinitionRegistrar的类,还可以通过@Import导入普通的POJO(将其注册成Spring Bean,导入POJO需要Spring 4.2以上版本)。 @Import的许多功能都需要借助接口ImportSelector来实现,ImportSelector决定可引入哪些@Configuration。
当AutoConfigurationImportSelector被@Import注解引入之后,它的selectImports方法会被调用并执行其实现的自动装配逻辑。selectImports方法几乎涵盖了组件自动装配的所有处理逻辑。让我们来看看AutoConfigurationImportSelector的selectImports方法源代码。
对于importSelector来说,有两种形式,
一种是实现 DeferredImportSelector,
一种是实现 ImportSelector。
DeferredImportSelector来说,不会通过调用 selectImports方法进行配置加载,
ImportSelector形式会通过selectImports方法进行配置加载;
DeferredImportSelector这种是先进行我们的 @Configruation配置的加载,然后进行其他(Autoconfig相关类)的加载;
ImportSelector先加载 Autoconfig相关类,然后加载@Configruation类。
主要是通过以下源码方法进行加载配置类
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
// 是否开启自动配置
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//获取注解的 属性(exclude 和 excludeName)
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取自动配置类。从spring.factories 中获取
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
//通过我们的注解属性,获取exclude的类
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
//检查 exclsions 里边的类是否是正规的类
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//筛选 configurations
configurations = getConfigurationClassFilter().filter(configurations);
// 事件发布
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}