Spring Boot Start 脚手架定制开发和快速入门
2024年3月9日 Spring Boot, Java l101782 minutes
介绍基于 start.spring.io
快速定制自己的 Spring Boot 脚手架,主要应用场景:
- 规范公司自己的 parent pom,增加特定的依赖项。
- 根据公司规范生成统一的包结构,统一命名。
- 根据需要增加特定代码或文件,比如根据公司要求统一 logback.xml、 application.properties 文件。
- 提供公司自研的二方 jar 包。
快速开始
基本步骤:
- 对于 spring.initializr 我们没有定制的需求,直接引用官方的。
- 拷贝一份 start.spring.io
,直接基于这个项目开发、部署、运行。以下都是关于如何修改
start.spring.io
。
start.spring.io
主要关注两个模块:
- start-client:前端页面,可以定制些自己的 logo、title 等。
- start-site:是一个标准的 spring boot 项目,实际 run 起来的服务,引用了 start-client,直接 run 这个项目的 main 方法就能看到效果。
主要配置文件:start-site/src/main/resources/application.yml
,通过修改这个配置文件可以达到的效果如下。
修改 start 启动时默认 group,把
com.example
改为公司自己的 group。initializr: group-id: value: com.yourgroup
修改父 pom,使用公司自己的 pom。
initializr: env: maven: # use your parent pom parent: groupId: com.yourself artifactId: your-parent version: 1.0.0 # relativePath: ../pom.xml includeSpringBootBom: false
限定 Java 和 Spring Boot 版:修改 languages 和 bootVersions 即可。
增加公司自己的 starter,参考文件中例子增加即可。
核心扩展接口
- ProjectContributor: 用于实现文件结构变化,比如加个文件夹,增加配置文件、代码片段等。
- BuildCustomizer:动态修改 pom.xml,用于修改 maven/gradle 的 dependencies/repository/plugins 等。
- 更多自带定制接口参考:MainSourceCodeCustomizer, MainCompilationUnitCustomizer, MainApplicationTypeCustomizer, TestSourceCodeCustomizer, TestApplicationTypeCustomizer.
场景:生成默认的 logback-spring.xml。
import io.spring.initializr.generator.project.contributor.SingleResourceProjectContributor;
/**
* 定制 logback xml 文件,从当前项目的`classpath:configuration`拷贝到指定的 src/main/resources 目录下
*/
public class LogbackContributor extends SingleResourceProjectContributor {
public LogbackContributor() {
this("classpath:configuration/logback-spring.xml");
}
public LogbackContributor(String resourcePattern) {
super("src/main/resources/logback-spring.xml", resourcePattern);
}
}
场景:按照统一规范生成目录结构。
/**
* 按照规范生成默认的 java 目录结构
*/
public class DefaultPackageContributor implements ProjectContributor {
private final ProjectDescription description;
public DefaultPackageContributor(ProjectDescription description) {
this.description = description;
}
@Override
public void contribute(Path projectRoot) throws IOException {
Language language = description.getLanguage();
// "src/main/java/com.test.demo"
Path packageRoot = projectRoot.resolve("src/main/")
.resolve(language.id())
.resolve(description.getPackageName().replaceAll("\\.","/"));
Files.createDirectories(packageRoot.resolve("config"));
Files.createDirectories(packageRoot.resolve("dao"));
Files.createDirectories(packageRoot.resolve("service"));
Files.createDirectories(packageRoot.resolve("web"));
}
}
场景:在 xxx 条件下做 xxx。比如我们使用 spock 作为测试框架,spock 使用 groovy 语言。如果引入 spock 的时候,默认在 maven plugin 里增加 groovy 插件 gmavenplus-plugin
。
class SpockMavenBuildCustomizer implements BuildCustomizer<MavenBuild> {
@Override
public void customize(MavenBuild build) {
// add groovy plugin
build.plugins()
.add("org.codehaus.gmavenplus", "gmavenplus-plugin");
}
}
@ProjectGenerationConfiguration
public class MyProjectGenerationConfiguration {
@Bean
@ConditionalOnRequestedDependency("spock")
public SpockMavenBuildCustomizer spockMavenBuildCustomizer() {
return new SpockMavenBuildCustomizer();
}
}