SpringBoot
自动装配原理
从Spring的IOC到SpringBoot的自动装配原理
DeferedImportSelector对Bean加载顺序的影响(当然是由@Import导入的)
DeferedImportSelector有一个分组的概念,如果自定义了一个类,实现了Group接口,可以在这里面自定义排序规则。
Group有延迟的特性,还有分组的特性。
扫描读取所有jar包当中的spring.factories文件,将文件中得配置读取到缓存中,为Map结构。
在这个过程,会排除和过滤掉不需要的自动配置类。
排除在EnableAutoConfiguration中可以配置要排除的自动配置类。
过滤则主要通过扫描spring.factories文件,找到对应key为:AutoConfigurationImportFilter,把对应配置了该key的配置类给过滤掉。比如:
比如有:@conditionalOnBean、@conditionalOnClass、@conditionalOnProperty
有时候要求要有相应配置或者项目中有相关类才配加载自动配置。
最后扫描了之后可以在DeferedImportSelector的selectImports()方法中进行排序了。sortAutoConfigurations。
所以也可以自定义一个starter。
启动原理
为什么SpringBoot的jar可以直接运行?
Java没有提供任何标准的方式来加载嵌套的jar文件。(即它们本身包含在jar中的jar文件)
用我自己的话来说,maven通过将多个maven-jar的插件,将依赖的jar文件打包到目标的jar包里面,以及会生成一个MAINFESTMF的文件,然后运行java -jar的时候会运行JarLauncher,之后通过反射,找到MAINFEST.MF文件中的启动类,通过反射调用,执行main方法,启动spring boot程序。
总结:
JarLauncher通过BOOT-INF/classes目录以及BOOT-INF/lib目录下jar文件,实现了fat jar的启动。
SpringBoot通过扩展JarFile、JarURLConnection以及URLStreamHandler,实现了jar in jar中资源的加载。
SpringBoot通过扩展URLClassLoader-LauncherURLClassLoader,实现了jar in jar中class文件的加载。
启动类new 一个spring 上下文对象干了什么事情?
总结:
1. 获取启动类;根据启动类加载IOC容器。
2. 获取web应用类型;
3. spring.factories读取了对外扩展的ApplicationContextInitializer,ApplicationListener(对外扩展,对内解耦,比如全局配置文件、热部署插件)
4. 根据main推算出所在的类。
具体执行run方法流程:
读取配置文件(通过监听者模式)
读取配置类,
解析配置类,加载spring容器,解析@component,@Bean等注册为BeanDefinition,然后创建为一个真正的Bean
SpringBoot是如何启动内置Tomcat的?
类似如下逻辑:
在selfInstialize(ServletContext servletContext)方法中可以获得DispatcherServlet,但是DispatcherServlet怎么来的呢?
有一个DispatcherServletAutoConfiguration的类,这里面自动注入的。而注册DispatcherServlet为Bean主要用的是ServletRegistryBean。而它又实现了ServletContextInitializer接口。
所以,在selfInstialize(ServletContext servletContext)中可以获得DispatcherServlet.
外置Tomcat是如何启动SpringBoot的?
由Tomcat通过SPI机制,读取ServletContainerInitializer的实现类:SpringServletContainerInitializer,进入该方法,要求Tomcat找到所有实现了WebApplicationInitializer的类,其中包括Dispatcher的。
在调用对应的onStartUp方法
在里面就注册了DispatcherServlet。而启动应用程序main方法用的就是SpringBootServletInitializer。
使用外置的Tomcat,除了要排除内置Tomcat依赖之外,还需要重写一个SpringBootServletInitializer对应接口的实现类:从而告诉tomcat应用程序的自动类是哪个