所谓自动配置那么就应该分成两步;一、自动;二、配置

一、springboot如何实现自动 

     springboot其实就是对spring的二次开发,能够实现自动主要是因为注解@EnableAutoConfiguration;注解中使用了@Import({AutoConfigurationImportSelector.class});AutoConfigurationImportSelector中又实现了DeferredImportSelector接口;DeferredImportSelector接口继承自ImportSelector;

Spring boot 自动刷新Bean springboot自动加载配置_spring boot

 

Spring boot 自动刷新Bean springboot自动加载配置_java_02

 所有实现ImportSelector在spring初始化的时候都会调用invokeBeanDefinitionRegistryPostProcessors,在spring中默认是通过类  org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry的方法来完成这个操作的;具体的调用链路可以参考如下链接:

AutoConfigurationImportSelector到底怎么初始化 - 简书

Spring boot 自动刷新Bean springboot自动加载配置_jar_03

二 配置

   1>根据第一步的操作, spring启动的时候会自动执行AutoConfigurationImportSelector下的process方法; 

Spring boot 自动刷新Bean springboot自动加载配置_加载_04

  2> processor中又会调用 #getAutoConfigurationEntry方法;其中的#getCandidateConfigurations调用

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());最后调用loadSpringFactories加载 "META-INF/spring.factories"配置文件通过反射初始化里面的所有类完成配置。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
        ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

三、SpringBoot配置外部tomcat如何启动 

servlet3.0规范 1>tomcat遵循了servlet3.0规范,在启动会去下图的特定目录的文件下查找实现了 接口ServletContainerInitializer的实现类, 并且调用onstart方法;参考如下链接:spring boot到底是怎么启动的_一个会写bug的dog的博客

Spring boot 自动刷新Bean springboot自动加载配置_加载_05

五、启动方式

5.1 ar包启动 

增加配置

Spring boot 自动刷新Bean springboot自动加载配置_spring_06

 生成MANIFEST.MF文件把依赖iar包也打包进去,生成一个fat jar,所有应用用到的jar嵌套进去。

1.通过spring-boot-plugin 生成了MNIFEST.MF,main-class 指定运行java -jar 的主程序,把依赖的jar文件 打包在fat jar.
2.JarLauncher通过加载BOOT-INF/classes目录及BOT-INF/lib目录下jar文件,实现了fat jar的启动。

3.SpringBoot通过扩展JarFile、JarURLConnection及RLStreamHandler,实现了iar in jar中资源的加载。

4.SpringBoot通过扩展URLClassLoader-LauncherURClassLoader,实现了iar in jar中class文件的加载。
5.WarLauncher通过加载WEB-INF/classes目录及WEB-INF/lib和WEB-INF/lib-provided目录下的jar文件,实现了war文件的直接启动及web容器中的启动。

MNIFEST.MF 文件内容

Spring boot 自动刷新Bean springboot自动加载配置_加载_07

 5.2 内置tomcat启动方式

        

Spring boot 自动刷新Bean springboot自动加载配置_java_08

5.3 外置tomcat启动方式

 利用SPI机制,找到所有实现ServletContainerInitializer的类,注解@HandlesTypes({WebApplicationInitializer.class}) 表示所有实现WebApplicationInitializer的类都会作为参数传入如下接口。

Spring boot 自动刷新Bean springboot自动加载配置_java_09

 

Spring boot 自动刷新Bean springboot自动加载配置_spring_10

 AbstractDispatcherServletInitializer是其中一个,他的onStartup方法初始化web应用上下文。

Spring boot 自动刷新Bean springboot自动加载配置_spring boot_11

 配置外部应用需要继承SpringBootServletIniyializer方法,重新configure方法,告诉启动类是哪个

Spring boot 自动刷新Bean springboot自动加载配置_spring boot_12

 

Spring boot 自动刷新Bean springboot自动加载配置_spring_13

Spring boot 自动刷新Bean springboot自动加载配置_加载_14