一、启动类分析 SpringApplication
1、构造函数初始化对象
构造四个对象,
private ResourceLoader resourceLoader;
//the primary bean sources 第一个主要的bean,入口类
private Set<Class<?>> primarySources;
//项目类型,默认servlet
private WebApplicationType webApplicationType;
private Class<?> mainApplicationClass;
-
1.1、设置ApplicationContextInitializer初始化这种类型的bean,主要通过(META-INF/spring.factories)声明的类
-
1.2、获取类型bean主要通过SpringApplication.getSpringFactoriesInstances这个方法获得
#这个方法会加载了各种配置,读取jar包下面的META-INF/spring.factories文件中声明的类名,
META-INF/spring.factories声明各种类 -
1.3、生成获取需要的Instrance,SpringApplication.createSpringFactoriesInstances
-
1.4、主要做了,获取入口main函数的类,
总结:META-INF/spring.factories文件中声明的类名,初始化了1.ApplicationContextInitializer和2.ApplicationListener两种,确定项目类型(web,还是其他),Sources类,就是注解了@SpringApplication的类
2、启动类run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
-
启动监听器SpringApplicationRunListeners,监听spring的启动的功能,spring启动的生命周期,
-
2.1 搞一个生命周期的stopWatch
-
2.2 初始化SpringApplicationRunListener监听器,监听spring的周期
-
2.3 ApplicationArguments处理java的arg参数,读取–spring=的启动参数
-
2.4 初始化ConfigurableEnvironment,初始化变量,拿ApplicationArguments进行处理,先拿到最出类型的StandardServletEnvironment,这个类是储存配置的和环境变量等变量
#配置类-添加PropertySource,这个是用来获取配置的
#web类型的初始化配置StandardServletEnvironment会加入以下的property变量
StandardServletEnvironment的PropertySource
StubPropertySource 用于占位
MapPropertySource 系统变量
SystemEnvironmentPropertySource 系统环境变量
#然后配置文件加入到environment中
configurePropertySources(environment, args);//加入命令行source,CompositePropertySource
configureProfiles(environment, args);
#将environment和SpringApplication类绑定在一起
使用Binder类绑定
这个类需要了解再去了解吧,Binder类,Binder类,Binder类,Binder类还不清楚怎么用
- 2.5 彩蛋打印banner 找classPath下的banner文件,可打印图片
- 2.6 生成createApplicationContext 生成spring上下文
#web使用, application context作文上下文
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
初始的AnnotationConfigServletWebServerApplicationContext的过程
1、这个类主要生成两个,注册器
AnnotatedBeanDefinitionReader 注解定义
ClassPathBeanDefinitionScanner classPath定义
AnnotatedBeanDefinitionReader
#用于处理注解的类,将environment环境配置数据做处理,查找各种注解并且处理
1、获取初始的AnnotationConfigServletWebServerApplicationContext(注册机)的DefaultListableBeanFactory
设置注解bean依赖的排序处理器,AnnotationAwareOrderComparator
添加ContextAnnotationAutowireCandidateResolver,Autowire condidate解决Lazy懒加载的处理
注册这些BeanDefinition
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
org.springframework.context.annotation.internalPersistenceAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
ClassPathBeanDefinitionScanner
#用户处理classPath的scanner扫描
- 2.7 处理spring启动异常处理器,初始化
#处理spring启动报错的异常
#META-INF/spring.factories下实现了SpringBootExceptionReporter这里的类
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
- 2.8 准备问上下文
#run入口中有
一、
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
二、prepareContext处理(提前准备一些springboot的配置类)
1、给context设置environment
2、postProcessApplicationContext(context);//设置ResourceLoader
3、applyInitializers,执行ApplicationContextInitializer,开放功能,执行init
4、listeners.contextPrepared(context);开放功能执行contextPrepared
5、注册两个bean,springApplicationArguments,springBootBanner//banner,jvm参数处理等
5、BeanDefinitionLoader加载数据,注册资源上的数据,资源类型有注解类,xml,classPath、这一步是主要的bean容器初始化。
//注册一些bean的信息由该doRegisterBean方法触发功能
{
5.1. 注册某些bean的定义
}
6、listeners.contextLoaded(context);推送监听器时间
三、refreshContext,开始初始化bean容器,(spring初始化的过程)
1、方法大概功能
主要的入口是AbstractApplicationContext的refresh() 方法
1.1 准备上下文的刷新的一些信息,PropertySources配置等
1.2 获取beanFactory工厂
1.3 beanFactory工厂使用当前上下文context
2、 invokeBeanFactoryPostProcessors,bean工厂的后置处理器
------在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
------所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
这里两种Bean定义后处理器
BeanDefinitionRegistryPostProcessor是在BeanFactoryPostProcessor的前面执行。
springboot会使用ConfigurationClassPostProcessor这个bean后处理器去扫描bean,注册bean这个类就是继承了BeanDefinitionRegistryPostProcessor的,加载一些配置类
2.1 重点springboot,配置bean注册后处理器,ConfigurationClassPostProcessor
2.2 解析处理,ConfigurationClassParser的parse方法
ClassPathBeanDefinitionScanner扫描,处理bean上面的注解,
useDefaultFilters,nameGenerator,scopedProxy,scopeResolver,resourcePattern,includeFilters,excludeFilters,lazyInit,basePackages,basePackageClasses,
等等属性,
最后doScan扫描一波包
scanner.doScan(StringUtils.toStringArray(basePackages));
把数据都注册到注册器的beanDefinition里面
2.3 到这一步,就已经把所有的beanDefinition定义已经都初始化好了
四、注册国际化语言MessageSource
五、注册initApplicationEventMulticaster时间监听bean,初始化时间委派器
六、onRefresh()准备好createWebServer,初始化TomcatServletWebServerFactory
tomcat工厂,然后初始化配置文件initPropertySources,
六、 Check for listener beans and register them.注册监听的bean到,初始化时间委派器中,:默认用:SimpleApplicationEventMulticaster
七、初始化所有非懒加载的bean,finishBeanFactoryInitialization
八、然后启动tomcat,推送各种事件,容器启动事件,tomcat启动事件,上下文启动事件,
九、执行callRunners,执行命令行等,
十、推送各种-spring运行时间