阿里云发布 Spring Boot 新脚手架,真香 (5)

6.png

在 application.yml 文件中,可以找到如下的配置信息,这里就是实际的项目依赖关系元数据的配置存储点:

7.png

整体来看,启动阶段的动作还是比较简单的,这也是为什么 start.spring.io 启动只需要数秒的原因。

更多的逻辑,都被留在了工程生成阶段。

2. 生成阶段

生成阶段,spring-initializr 使用了一个很有意思的实现方式:initializr 框架会为每一次项目生成,创建一个独立的 context 用于存放生成流程中需要使用到的各种 bean 。

先来一张时序图:

8.png

蓝色的类,是在应用启动阶段就完成了创建和数据填充;其生命周期和整个应用一致;

黄色的类,会在具体的项目构建过程中生成;其生命周期在一次项目生成流程之内结束。

从上面的时序图中可以看出:一个典型的创建行为,通常从 ProjectGenerationController收到web端的创建请求开始,通过 ProjectGenerationInvoker 这个中间层转换,最终进入 ProjectGenerator 的核心构建流程。

主干流程

下图,是 ProjectGenerator 的核心构建流程:

9.png

106 行,通过 contextFactory 构建了一个新的 ProjectGenerationContext 。

看一下这个context的继承关系,原来于spring提供的AnnotationConfigApplicationContext 。

再结合 110 行的 refresh() 方法,是不是发现了什么?就是 spring 的 ApplicationContext 的刷新流程。

10.png

107 行的 resolve 方法,向 context 中注册了一个 ProjectDescription的Provider,代码如下:

10(1).png

由于注册的是 Provider ,所以这段逻辑会在 Context 执行 refresh 时运行。

这里的 ProjectDescriptionCustomizer 就是针对 ProjectDescription 的扩展,用于对用户传入的 ProjectDescription 做调整。这里主要是一些强制依赖关系的调整,例如语言版本等。

这时候再看 108 行,这里向 Context 注册一个 Configuration 。

那么这个 Configuration 包含了什么内容呢?一起来看下面这段代码:

11.png

ProjectGenerationConfiguration!!!前面提到的 spring.factories 中有很多这个 SPI 的实现(参见参考资料)。

原来,initializr 的整个扩展体系,在这里才开始创建实例;

ProjectGenerator 的 109 行,对一个 consumer 做了 accept 操作;其实就是调用了下面的代码:

12.png

这里通过 setParent 将应用的主上下文设置为这次 ProjectGenerationContext 的父节点。

并且向这次 ProjectGenerationContext 中注册了元数据对象。

最后,在 ProjectGenerator 的 112 行,调用了 projectAssetGenerator 的 generate 方法,实现如下:

13.png

通过上面的代码可以发现,这里对实际的工程构建工作,其实就是很多的 ProjectContributor 共同叠加;

至此,主干流程已经结束了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwpzdz.html