创建SpringApplication对象,
—判断容器类型(web or dapp)
—设置ApplicationContextInitializer到对象SpringApplication中
-------利用SpringFactoriesLoader类加载classpath下的META-INFO/spring.factories文件中定义的类路径,名称缓存到SpringFactoriesLoader.cache中
-------加载类ApplicationListener到对象SpringApplication中
调用run方法
------初始化SpringApplicationRunListeners对象
------从factory定义的类中加载SpringApplicationRunListener类(boot EventPublishingRunListener),并传入之前容器定义的各种监听器
------EventPublishingRunListener实现类中定义消息广播器,发布
调用SpringApplicationRunListeners.starting方法,发布ApplicationStartingEvent
------默认LoggingApplicationListener类消费到消息,开始准备日志系统
---------springboot默认logback,移除jdk日志框架handler,设置slf4j
------LiquibaseServiceLocatorApplicationListener消费到消息,进行springboot替换
---------创建环境变量对象StandardServletEnvironment
------发布ApplicationEnvironmentPreparedEvent 默认4个监听器会收到通知
---------FileEncodingApplicationListener :spring.mandatory-file-encoding不为空时检测是否与file.encoding一致,不一致抛出异常
---------AnsiOutputApplicationListener :终端支持彩色则输出彩色日志
---------ConfigFileApplicationListener: 加载进去5个EnvironmentPostProcessor
SystemEnvironmentPropertySourceEnvironmentPostProcessor: 将操作系统环境变量配置加载到环境变量中
SpringApplicationJsonEnvironmentPostProcessor:解析 spring.application.json 或 SPRING_APPLICATION_JSON 配置的 json 字符串
CloudFoundryVcapEnvironmentPostProcessor:对CloudFoundry提供支持
DebugAgentEnvironmentPostProcessor: to enable the Reactor Debug Agent if available
---------DelegatingApplicationListener :默认情况下未做任何处理
---------ClasspathLoggingApplicationListener :输出classpath路径
------环境变量绑定到application对象上
------输出logo
------创建spring容器对象(默认AnnotationConfigServletWebServerApplicationContext)
------进行容器准备
------将之前创建的ConfigurableEnvironment交给容器
------发布ApplicationContextInitializedEvent
------打印日志
------将printedBanner注册到容器
------将spring容器加到之前的监听器中,并把监听器也注册到该容器中
------发布ApplicationPreparedEvent
---------ConfigFileApplicationListener消费到消息,创建PropertySourceOrderingPostProcessor加入到BeanFactoryPostProcessor中
---------刷新spring容器
---------发布ApplicationStartedEvent
---------扫描容器中所有ApplicationRunner与CommandLineRunner实现类,依次执行
---------发布ApplicationReadyEvent
------容器创建异常后
---------发布ExitCodeEvent
---------查找之前注册的异常广播类处理异常
1 ApplicationContextInitializer
ApplicationContextInitializer是Spring框架原有的概念, 这个类的主要目的就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext做refresh之前,允许我们对ConfigurableApplicationContext的实例做进一步的设置或者处理。
通常用于需要对应用程序上下文进行编程初始化的web应用程序中。例如,根据上下文环境注册属性源或激活概要文件。
参考ContextLoader和FrameworkServlet中支持定义contextInitializerClasses作为context-param或定义init-param。
ApplicationContextInitializer支持Order注解,表示执行顺序,越小越早执行;
SpringBoot内置6个ApplicationContextInitializer
下面列出了一个使用缺省配置的Springboot web应用默认所使用到的ApplicationContextInitializer实现们:
1.1 DelegatingApplicationContextInitializer**
使用环境属性context.initializer.classes指定的初始化器(initializers)进行初始化工作,如果没有指定则什么都不做。
通过它使得我们可以把自定义实现类配置在application.properties里成为了可能。
1,2 ContextIdApplicationContextInitializer**
设置Spring应用上下文的ID,会参照环境属性。至于Id设置为啥值会参考环境属性:
spring.application.name
vcap.application.name
spring.config.name
spring.application.index
vcap.application.instance_index
如果这些属性都没有,ID使用application。
1.3 ConfigurationWarningsApplicationContextInitializer
对于一般配置错误在日志中作出警告
1.4 ServerPortInfoApplicationContextInitializer
将内置servlet容器实际使用的监听端口写入到Environment环境属性中。这样属性local.server.port就可以直接通过@Value注入到测试中,或者通过环境属性Environment获取。
1.5 SharedMetadataReaderFactoryContextInitializer
创建一个SpringBoot和ConfigurationClassPostProcessor共用的CachingMetadataReaderFactory对象。实现类为:ConcurrentReferenceCachingMetadataReaderFactory
ConditionEvaluationReportLoggingListener
将ConditionEvaluationReport写入日志。
1.6 AutoConfigurationReportLoggingInitializer
2 ApplicationLinstener
2.1 ClearCachesApplicationListener
当接收到上下文刷新事件时,清空当前线程的缓存。
2.2 ParentContextCloserApplicationListener
当收到应用上下文关闭事件后,去关闭其可能存在的活动的子上下文。
2.3 CloudFoundryVcapEnvironmentPostProcessor,
2.4 FileEncodingApplicationListener
如果spring.mandatory-file-encoding的值(忽略大小写)与file.encoding的值不相等,则直接报错,直接不让程序运行。比如我们设置了spring.mandatory-file-encoding=utf-8,file.encoding的值为GBK则报错;如果spring.mandatory-file-encoding=uTF-8,file.encoding的值为utf-8就不会报错。因为比较两者值的时候已经忽略大小写了。
2.5 AnsiOutputApplicationListener
application.properties配置文件中增加上面两个配置项,控制台可打印彩色日志
spring.output.ansi.enabled=ALWAYS
2 console-available=true
2.6 ConfigFileApplicationListener
主要作用就是读取应用的配置文件并add到Environment的PropertySources列表里
2.7 DelegatingApplicationListener
监听ApplicationEnvironmentPreparedEvent事件(Environment已经准备好但是Context还没有创建事件),
读取Environment中的context.listener.classes属性值(监听器类全路径,多个以逗号隔开)来创建ApplicationListene
加载并转载事件到context.class.listener中配置的applicationListener中
2.8 ClasspathLoggingApplicationListener,\
启动成功后,将classpath打印到debug日志中,失败则打印至info中
2.9 LoggingApplicationListener
根据配置在合适时候创建日志系统
2.10 LiquibaseServiceLocatorApplicationListener
classpath中存在类liquibase.serviceLocator.serviceLocator,将其替换成springboot版本
EnvironmentPostProcessor
在/Users/naeshihiroshi/study/studySummarize/SpringBoot/(自己测试也可以随机在一个目录下建立一文件),目录下建立一个名为springboot.properties文件,
springboot.properties中定义一些配置,配置如下:
jdbc.root.user=zhihao.miao
jdbc.root.password=242312321
定义MyEnvironmentPostProcessor实现EnvironmentPostProcessor接口
@Componentpublic class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
try{
InputStream inputStream = new FileInputStream("/Users/naeshihiroshi/study/studySummarize/SpringBoot/springboot.properties");
Properties properties = new Properties();
properties.load(inputStream);
PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource("my",properties);
environment.getPropertySources().addLast(propertiesPropertySource);
}catch (IOException e){
e.printStackTrace();
}
}}
CloudFoundryVcapEnvironmentPostProcessor
SpringApplicationJsonEnvironmentPostProcessor
SystemEnvironmentPropertySourceEnvironmentPostProcessor
DebugAgentEnvironmentPostProcessor
SpringBootExceptionReporter
1 FailureAnalyzers
SpringApplicationRunListener
PropertySourceLoader
FailureAnalyzer
FailureAnalysisReporter
AutoConfigurationImportListener
AutoConfigurationImportFilter
EnableAutoConfiguration
IOC原理
容器启动时流水线解析
AnnotationConfigApplicationContext使用
//未做重要处理 仅仅将对象AnnotatedBeanDefinitionReader与ClassPathBeanDefinitionScanner 装入对象ClassPathBeanDefinitionScanner中
AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext();
//扫描各种重要组件 包括使用了各种注解的类 如@Component等
//扫描各种类 并创建相应BeanDefinition并注册到DefaultListableBeanFactory中的map中
c.scan("com.spring");
//处理加载的各种bean
c.refresh();
//启动容器
c.start();
spring SPI机制使用
org.springframework.core.io.support.SpringFactoriesLoader
加载classpath路径下的所有META-INF/spring.factories文件,加载后会缓存到静态属性ConcurrentReferenceHashMap对象中