我们可以发现,在主干流程中,没有做任何写文件的操作(只创建了根文件夹);它仅仅是定义了一套数据加载、扩展加载的机制与流程,将所有的具体实现都作为扩展的一部分。
扩展流程spring-initializr 提供了 2 种主要扩展途径:ProjectContributor 和 xxxxxCustomizer。
从方法签名就可以看出,入参只有一个项目的根路径,其职责就是向这个路径下些人项目文件。这个扩展点非常的灵活,几乎可以支持任何的代码、配置文件写入工作。
实现过程中,可以通过 ProjectGenerationContext 获取相关依赖,然后通过自定义逻辑完成文件生成工作。
下面是 initializr 和 start.spring.io 提供的 ProjectContributor 实现:
拿几个主要的实现看看:
MavenBuildProjectContributor:写入 maven 项目 pom.xml 文件;
WebFoldersContributor:创建 web 项目的资源文件夹;
ApplicationPropertiesContributor:写入 application.properties 文件;
MainSourceCodeProjectContributor:写入应用入口类 xxxApplication.java 文件;
HelpDocumentProjectContributor:写入帮助文档 HELP.md 文件。
相对于 ProjectContributor,xxxxxCustomizer 不是一个统一的接口,我把他理解为一种感念和与之对应的命名习惯;每个 Customizer 都有自己明确的名字,同时也对应了明确的触发逻辑和职责边界。
下面列出框架提供的 Customizer 的说明:
MainApplicationTypeCustomizer:自定义 MainApplication 类;
MainCompilationUnitCustomizer:自定义 MainApplication 编译单元;
MainSourceCodeCustomizer:自定义 MainApplication 源码;
BuildCustomizer:自定义项目构建工具的配置内容;
GitIgnoreCustomizer:自定义项目的 .gitignore 文件;
HelpDocumentCustomizer:自定义项目的帮助文档;
InitializrMetadataCustomizer:自定义项目初始化配置元数据;这个 Customizer 比较特殊,框架会在首次加载元数据配置时调用;
ProjectDescriptionCustomizer:自定义 ProjectDescription ;即在生成项目文件之前,允许调整项目描述信息;
ServletInitializerCustomizer:自定义 web 应用在类上的配置内容;
TestApplicationTypeCustomizer:自定义测试 Application 类;
TestSourceCodeCustomizer:自定义测试 Application 类的源码。
参考资料 1. 相关链接initializr 说明文档
https://docs.spring.io/initializr/docs/current-SNAPSHOT/reference/html/
spring-initializr 项目地址
https://github.com/spring-io/initializr
start.spring.io 项目地址
https://github.com/spring-io/start.spring.io
2. spring.factories 明细 initializr-generator/src/main/resources/META-INF/spring.factoriesio.spring.initializr.generator.buildsystem.BuildSystemFactory=\ io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystemFactory,\ io.spring.initializr.generator.buildsystem.maven.MavenBuildSystemFactory io.spring.initializr.generator.language.LanguageFactory=\ io.spring.initializr.generator.language.groovy.GroovyLanguageFactory,\ io.spring.initializr.generator.language.java.JavaLanguageFactory,\ io.spring.initializr.generator.language.kotlin.KotlinLanguageFactory io.spring.initializr.generator.packaging.PackagingFactory=\ io.spring.initializr.generator.packaging.jar.JarPackagingFactory,\ io.spring.initializr.generator.packaging.war.WarPackagingFactoryinitializr-generator-spring/src/main/resources/META-INF/spring.factories:
io.spring.initializr.generator.project.ProjectGenerationConfiguration=\ io.spring.initializr.generator.spring.build.BuildProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.build.gradle.GradleProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.build.maven.MavenProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.code.SourceCodeProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.code.groovy.GroovyProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.code.java.JavaProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.code.kotlin.KotlinProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.configuration.ApplicationConfigurationProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.documentation.HelpDocumentProjectGenerationConfiguration,\ io.spring.initializr.generator.spring.scm.git.GitProjectGenerationConfiguration