• 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;
        }
  • 相关阅读:
    (剑指Offer)面试题18:树的子结构
    (剑指Offer)面试题17:合并两个排序的链表
    (剑指Offer)面试题16:反转链表
    程序员水平分级 你属于哪一类?
    Hacker
    十分钟让你看懂中国经济形势,10分钟,坚持看完,必有所获~(转载)
    人口问题,怎样的生育率才能保持正常的世代更替?
    理科和文科的区别?
    柴晓霞:做销售要学会画蓝图 (转载)
    工作,为钱还是为理想
  • 原文地址:https://www.cnblogs.com/LQBlog/p/15945534.html
Copyright © 2020-2023  润新知