@SpringBootApplication注解源码解析

2023-10-29

一. SpringBoot 启动类注解 @SpringBootApplication

  1. @SpringBootApplication 注解源码,该注解是一个复合注解,通过@SpringBootConfiguration注解提供设置类为配置类功能,通过@ComponentScan 提供扫描当前类同级与子级包下的所有类开启,添加到容器中,通过@EnableAutoConfiguration 实现SpringBoot的自动配置功能
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //增加配置类功能
@EnableAutoConfiguration //SpringBoot自动配置的核心
@ComponentScan( //扫描当前目录类的所在同级或子级包下的所有类
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};

    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

二. SpringBoot 实现自动配置的核心 @EnableAutoConfiguration

  1. SpringBoot实现自动配置的核心 @EnableAutoConfiguration ,该注解中通过@Import({AutoConfigurationImportSelector.class}),向容器中import了一个AutoConfigurationImportSelector
@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 {};
}
  1. 查看 AutoConfigurationImportSelector,该类通过DeferredImportSelector间接实现了 ImportSelector接口,启动容器时会执行重写该接口的selectImports()方法,向容器中注入
    在这里插入图片描述
  2. 查看 AutoConfigurationImportSelector 的 selectImports() 方法,该方法中加载META-INF/spring.factories 文件,获取文件中类的全限定名,初始化SpringBoot需要的组件,配置类等等
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }


	protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            //该方法最终会调用一个loadSpringFactories()方法读取 META-INF/spring.factories 文件,获取文件中类的全限定名
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            //对spring.factories读取到的全限定名去重
            configurations = this.removeDuplicates(configurations);
            //排除掉不需要的,例如@SpringBootApplication (exclude={}),去除自动装载的类
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            //过滤被@ConditionalOnXxx修饰的,条件判断注入bean
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

@SpringBootApplication注解源码解析 的相关文章

随机推荐