所谓自动配置那么就应该分成两步;一、自动;二、配置
一、springboot如何实现自动
springboot其实就是对spring的二次开发,能够实现自动主要是因为注解@EnableAutoConfiguration;注解中使用了@Import({AutoConfigurationImportSelector.class});AutoConfigurationImportSelector中又实现了DeferredImportSelector接口;DeferredImportSelector接口继承自ImportSelector;
所有实现ImportSelector在spring初始化的时候都会调用invokeBeanDefinitionRegistryPostProcessors,在spring中默认是通过类 org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry的方法来完成这个操作的;具体的调用链路可以参考如下链接:
AutoConfigurationImportSelector到底怎么初始化 - 简书
二 配置
1>根据第一步的操作, spring启动的时候会自动执行AutoConfigurationImportSelector下的process方法;
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的博客
五、启动方式
5.1 ar包启动
增加配置
生成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 文件内容
5.2 内置tomcat启动方式
5.3 外置tomcat启动方式
利用SPI机制,找到所有实现ServletContainerInitializer的类,注解@HandlesTypes({WebApplicationInitializer.class}) 表示所有实现WebApplicationInitializer的类都会作为参数传入如下接口。
AbstractDispatcherServletInitializer是其中一个,他的onStartup方法初始化web应用上下文。
配置外部应用需要继承SpringBootServletIniyializer方法,重新configure方法,告诉启动类是哪个