Spring Boot-源码阅读-自动化Starter原理(四)

说明

使用方式参考Spring Boot-Starter(九)

原理:在Spring Boot-源码阅读-启动主流程(一) <14-18>处会将启动类封装成BeanDefinition 交给容器初始化。启动类都打了@SpringBootApplication注解

@SpringBootApplication
public class FinancialAnalysisApplication {

    public static void main(String[] args) {
        SpringApplication.run(FinancialAnalysisApplication.class, args);
    }

}

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

EnableAutoConfiguration

@Import使用方式可参考https://www.cnblogs.com/LQBlog/p/15410425.html

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)//通过Selector触发
public @interface EnableAutoConfiguration {
}

 

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

 @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        //<1>加载需要注入容器的类全名称通过AutoConfigurationEntry封装
        AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
        //转换成累的全名称
        return org.springframework.util.StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

<1>

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry

 protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        //<2>获取自动化配置类的名字
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        configurations = removeDuplicates(configurations);
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = getConfigurationClassFilter().filter(configurations);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
    }

<2>

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry

 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        //从Spring.factories获取对应的配置类
        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;
    }

   
    protected Class<?> getSpringFactoriesLoaderFactoryClass() {
        return EnableAutoConfiguration.class;
    }

 

posted @ 2022-02-28 14:31  意犹未尽  阅读(53)  评论(0编辑  收藏  举报