前言
基于上次沸点7天打卡,这边给大家简单的讲解下我理解的启动流程(细枝末节可能被我给pass掉,毕竟是Spring啊,本次基于spring-boot-starter-parent~2.1.6.RELEASE)。
流程启动
这里讲解的是Spring启动的一部分相关,目前里面涉及到的是一个简单的一个Web工程。
那我们就从SpringApplication.run(ServiceApplication.class, args);开始:
流程一
方法进去首先new了个对象:new SpringApplication(primarySources),让我们看看里面有哪些东西进行处理
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }复制代码
上述代码中:
- primarySources则是当前用户启动类类型。
- webApplicationType则是判断当前运行环境。共有三种选择。
- 在当前类加载器或者环境变量中META-INF/spring.factories搜寻类型为ApplicationContextInitializer的类,并将其加入当前属性变量集合中。
- 同3而言,搜寻类型为ApplicationListener的类,将其加入当前属性变量中(此时通过类加载器缓存集合中取,不需要再次扫描文件,3已经将所有配置加入到类加载器缓存中)
流程二
接下来就是实例的run方法进行,这里挑选出一部分。
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);复制代码
StopWatch的作用就是计时。
configureHeadlessProperty()用于系统的配置模式。Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。
getRunListeners(args)从当前ClassLoader下面META-INF/spring.factories或者从系统资源里面获取名称-在通过反射进行创建实例(EventPublishingRunListener),这里也是从ClassLoader缓存中读取。
new DefaultApplicationArguments(args)构造命令行启动参数对象。
prepareEnvironment(listeners, applicationArguments)这个方法里面主要为了Environment环境的创建准备。
- 根据webApplicationType类型,创建出对应的环境Bean(这里是new StandardServletEnvironment())。
- 添加类型转化器-ApplicationConversionService。(双锁volatile实例校验)。
- 在此应用程序的环境中添加、删除或重新排序任何propertsource,也就是将main中的args附加在PropertySources中。
- environment设置初始ActiveProfiles。
- listeners开始传播environmentPrepared准备好的事件(设置systemEnvironment以及加载当前Resource下的配置文件到环境中)。
- 将环境对象绑定至SpringApplication。
- 判断是否是自定义环境,是否将给定的环境转换为给定的标准环境类型。
- PropertySourceList队首添加SpringConfigurationPropertySources配置(使环境管理的每个PropertySource适应一个ConfigurationPropertySource)。
设置spring.beaninfo.ignore=true(值为true跳过了对BeanInfo类的搜索(通常用于在应用程序中首先没有为bean定义此类的场景))。
banner资源获取判断打印。
上述的代码片段中完整的讲述了项目启动的一部分过程(细枝末微的可能没有提及到),不过环境配置组成也说的很多部分,其实主要关注如何加载Bean到容器中以及事件通知之后做了哪些事情。