SpringBoot分析
启动分析
org.springframework.boot.SpringApplication
javax.servlet.Servlet
org.springframework.web.context.ConfigurableWebApplicationContext
org.springframework.context.ApplicationContextInitializer
org.springframework.context.ConfigurableApplicationContext
org/springframework/core/io/support/SpringFactoriesLoader.java
从下面三个文件里面加载工厂类 基本上配置的类都是从下面获取的(能不能自己搞一个spring.factories用来加载自己的类???)
jar:file:/home/away/.m2/repository/org/springframework/boot/spring-boot/2.0.3.RELEASE/spring-boot-2.0.3.RELEASE.jar!/META-INF/spring.factories
jar:file:/home/away/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.0.3.RELEASE/spring-boot-autoconfigure-2.0.3.RELEASE.jar!/META-INF/spring.factories
jar:file:/home/away/.m2/repository/org/springframework/spring-beans/5.0.7.RELEASE/spring-beans-5.0.7.RELEASE.jar!/META-INF/spring.factories
设置初始化 工厂getSpringFactoriesInstances
org.springframework.context.ApplicationContextInitializer
下面是从上面配置文件找到的初始化上下文的类
0 = “org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer”
1 = “org.springframework.boot.context.ContextIdApplicationContextInitializer”
2 = “org.springframework.boot.context.config.DelegatingApplicationContextInitializer”
3 = “org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer”
4 = “org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer”
5 = “org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener”
设置监听器 工厂getSpringFactoriesInstances
org.springframework.context.ApplicationListener
0 = “org.springframework.boot.ClearCachesApplicationListener”
1 = “org.springframework.boot.builder.ParentContextCloserApplicationListener”
2 = “org.springframework.boot.context.FileEncodingApplicationListener”
3 = “org.springframework.boot.context.config.AnsiOutputApplicationListener”
4 = “org.springframework.boot.context.config.ConfigFileApplicationListener”
5 = “org.springframework.boot.context.config.DelegatingApplicationListener”
6 = “org.springframework.boot.context.logging.ClasspathLoggingApplicationListener”
7 = “org.springframework.boot.context.logging.LoggingApplicationListener”
8 = “org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener”
9 = “org.springframework.boot.autoconfigure.BackgroundPreinitializer”
处理主类
deduceMainApplicationClass
run
新建秒表stopWatch
设置执行监听器 工厂getSpringFactoriesInstances
org.springframework.boot.SpringApplicationRunListener 这个监听器监听的是org.springframework.boot.SpringApplication的run方法 ,EventPublishingRunListener实现该接口。
org.springframework.boot.SpringApplicationRunListeners 是SpringApplicationRunListener监听器的容器,当事件触发的时候调用里面的监听器链
0=“org.springframework.boot.context.event.EventPublishingRunListener“
org.springframework.context.event.ApplicationEventMulticaster 管理org.springframework.context.ApplicationListener对象(就是上面十个监听器) multicastEvent方法用来通过event广播对应的listener。具体实现类org.springframework.context.event.SimpleApplicationEventMulticaster
org.springframework.boot.context.event.EventPublishingRunListener 这个通过ApplicationEventMulticaster管理上面十个监听器的。
理一下逻辑:
SpringApplicationRunListeners管理SpringApplicationRunListener这个对象,EventPublishingRunListener是SpringApplicationRunListener子类,EventPublishingRunListener对象触发很多event如(ApplicationStartingEvent),通过ApplicationEventMulticaster类将event广播到listener上
Event代理 org.springframework.context.event.ApplicationEventMulticaster
org.springframework.context.event.SimpleApplicationEventMulticaster
启动流程
starting
触发org.springframework.boot.context.event.ApplicationStartingEvent这个事件,然后调用所有监听者(10个) 找到关于这个事件的子类supportsEvent
/home/away/.m2/repository/org/springframework/spring-context/5.0.7.RELEASE/spring-context-5.0.7.RELEASE-sources.jar!/org/springframework/context/event/AbstractApplicationEventMulticaster.java:223
environmentPrepared
contextPrepared
contextLoaded
started
running
failed
org.springframework.context.event.GenericApplicationListenerAdapter#GenericApplicationListenerAdapter 这个适配器用的很精髓,再不修改原监听器的前提下,让每个监听器都拥有了检查事件是否触发自己的能力。
十个监听器的作用
ConfigFileApplicationListener:在EnvironmentPrepared阶段读取application.properties或者’application.yml’里面的属性,通过实现SmartApplicationListener接口,来决定被哪个事件触发
AnsiOutputApplicationListener:在EnvironmentPrepared阶段设置环境变量spring.output.ansi.enabled,通过实现ApplicationListener,里面的泛型具体类来确定被哪个事件触发
LoggingApplicationListener:在ApplicationStarting,ApplicationEnvironmentPrepared,ApplicationPrepared,ContextClosed,ApplicationFailed阶段记录日志,这个通过实现GenericApplicationListener这个类来确定被那个事件触发
ClasspathLoggingApplicationListener在EnvironmentPrepared,ApplicationFailed阶段记录线程的类加载器的路径
BackgroundPreinitializer:在SpringApplicationEvent的子类都会触发,用后台线程提前初始化耗时的任务。开启一个线程初始化信息,包括(1.MessageConverter用来http请求的转化;)需要看看具体实现?
工具类
ResolvableType 对java.lang.reflect.Type进行了封装,可以获取所有类型的信息(原始数据类型和类的信息)
HttpMessageConverter接口
org.springframework.http.converter.HttpMessageConverter是http请求和返回转化接口。
http头协议
“application/x-www-form-urlencoded”
MimeType
org.springframework.util.MimeType
参考https://tools.ietf.org/html/rfc2046
https://zh.wikipedia.org/wiki/多用途互聯網郵件擴展
http://www.ruanyifeng.com/blog/2008/06/mime.html 通俗易懂MIME的全称是"Multipurpose Internet Mail Extensions",中译为"多用途互联网邮件扩展
从邮件协议的发展 解决电子邮件只能发送英文的问题 主要是 定制了Content-Type: [type]/[subtype]; parameter(Content-Type: text/html; charset=gbk) 等头协议,之后也用到了http协议
org.springframework.http.MediaType里面主要包含了Content-Type:里面的值,算是MIMETYPE的具体实现。
转义字符
http://tool.oschina.net/commons?type=2
&#**;通常是html的转义字符