看了spring 2.4.5的源码,记录一下关键步骤
注意里面一些经常调用的方法
根据当前项目类型创建对象
WebApplicationType=NONE
WebApplicationType=SERVLET
WebApplicationType=REACTIVE
doWithListeners方法
通过EventPublishingRunListener发布event事件
根据event类型对listeners进行一个筛选,剩下的listeners对应事件进行一个处理
getSpringFactoriesInstances方法
通过查找META/INF下面的spring.factories文件,根据key(传入的类全名)去找到对应的value,value是一组类全名,使用反射将这些类进行一个实例化,存储在cache中
启动流程(当前只挑了重要的)
1.new SpringApplication()
开始的时候先new了一个SpringApplication对象,new对象的时候做了一些操作
①根据当前类判断当前应用类型
②从spring.factories文件中根据类全名key获取引导注册初始化器实例
③从spring.factories文件中根据类全名key获取初始化器实例
④从spring.factories文件中根据类全名key获取监听器实例
⑤将当前主类名存入到Application对象中
2.new SpringApplication().run()
new完对象之后运行对象的run方法
3.StopWatch stopWatch = new StopWatch();
stopWatch.start();
创建一个计时器,开始计时
4.DefaultBootstrapContext bootstrapContext = createBootstrapContext();
使用引导注册初始化器创建引导上下文
5.SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
从spring.factories文件中根据类全名key获取运行时监听器PublishEventRunListener并执行starting方法,通过doWithListeners向所有监听器广播starting事件
- ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
将传入的命令行参数根据–key=value的形式进行解析封装成ApplicationArguments对象
7.ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
准备环境对象,里面做了一些步骤
①根据当前应用类型创建或获取环境
②配置环境
③触发PublishEventRunListener的广播方法,广播环境创建的事件
8.Banner printedBanner = printBanner(environment);
打印banner,从对应目录下找是否有banner.png,banner.gif,banner.jpg的文件,如果有,就进行该文件的打印,如果没有,继续找是否有banner.txt的文件,如果有,打印,最后如果都找不到,打印默认的
9.context = createApplicationContext();
根据当前应用类型创建上下文,创建的时候创建了两个用来扫描注解的对象reader和scanner,然后父类还创建了DefaultListableBeanFactory对象
10.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
准备上下文
①执行初始化器的初始化方法
②触发PublishEventRunListener的广播方法,广播环境准备上下文的事件
③关闭引导上下文
④load方法将当前主类加载放到context中
⑤触发PublishEventRunListener的广播方法,广播上下文加载完毕的事件
11.refreshContext(context);
刷新上下文,里面执行了spring中的刷新方法,并且嵌入了tomcat的创建和启动流程,还嵌入了自动装配的流程
12.afterRefresh(context, applicationArguments);
afterRefresh,空实现,扩展方法
- stopWatch.stop();
停止计时器,进行用时的打印
14.listeners.started(context);
触发PublishEventRunListener的广播方法,广播started的事件
15.listeners.running(context);
触发PublishEventRunListener的广播方法,广播running的事件