Spring Boot 项目中的 Description 并不是一个独立依赖,而是构建元数据和应用运行信息中经常被忽略的描述字段。整合它的目标是把 pom.xml 或 build.gradle 中的描述文本,与 Actuator 端点、启动日志联动起来,形成从构建期到运行期都可见的说明信息。很多团队只在创建工程时随意写一句描述,之后既不在接口里暴露,也不在启动日志里输出,遇到多服务排障时只能逐个翻代码仓库,效率很低。

构建工具中写入描述字段
Maven 项目的描述信息来自 pom.xml 中的 <description> 标签。这个标签位于 project 根节点下,通常放在 artifactId 之后。它会被 Maven 打包进 jar 包的 META-INF/MANIFEST.MF 文件中,也会出现在 maven-metadata 里。如果项目后续要发布到私有仓库,描述信息会直接影响仓库页面的说明内容。下面是一个最小配置:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>order-service</artifactId>
<version>1.0.0</version>
<name>order-service</name>
<description>订单服务:负责创建、查询和取消订单</description>
</project>
Gradle 的处理方式更直接,在 build.gradle 里给 description 属性赋值即可。Groovy DSL 和 Kotlin DSL 都支持,而且可以与 version、group 等元数据放在一起。构建脚本中设置描述后,Gradle 生成的 POM 文件会自动带上这个字段,方便与 Maven 生态互通。
description = '订单服务:负责创建、查询和取消订单' version = '1.0.0' group = 'com.example'
需要注意的是,构建工具里的描述信息只在构建期生效。如果服务已经打成 jar 包运行,再去修改 pom.xml 不会影响正在运行的进程。要让运行中的服务也能读到描述,就需要把信息写入应用配置并通过 Actuator 暴露出来,这是下一节要处理的内容。
借助 Actuator 暴露描述信息
Spring Boot Actuator 的 info 端点非常适合展示应用描述。只需要引入 spring-boot-starter-actuator,然后在 application.yml 的 info 节点下添加自定义字段。下面的配置把 health 和 info 两个端点开放到 Web 访问,同时定义 app.name、app.description 和 app.version,查询 /actuator/info 时就能直接看到这些文本。
management:
endpoints:
web:
exposure:
include: health,info
info:
app:
name: order-service
description: 订单服务:负责创建、查询和取消订单
version: 1.0.0
如果描述信息需要从构建元数据中自动读取,而不是在 yml 里再手写一遍,可以借助 build-info 目标生成 build-info.properties,然后注入 BuildProperties 对象。Maven 的 spring-boot-maven-plugin 在 repackage 阶段可以生成该文件,Gradle 的 spring-boot 插件也有对应任务。接着实现 InfoContributor 接口,把构建描述动态放进 info 端点。
@Component
public class CustomInfoContributor implements InfoContributor {
private final BuildProperties buildProperties;
public CustomInfoContributor(BuildProperties buildProperties) {
this.buildProperties = buildProperties;
}
@Override
public void contribute(Info.Builder builder) {
Map<String, Object> details = new HashMap<>();
details.put("description", buildProperties.get("description"));
details.put("artifact", buildProperties.getArtifact());
details.put("version", buildProperties.getVersion());
builder.withDetail("app", details);
}
}
这种方式的优势是描述信息只维护一份,构建元数据是唯一来源,运行时的 info 端点始终与打包版本保持一致。但要注意 build-info 默认不一定开启,Maven 需要在插件配置里显式添加 execution,否则 BuildProperties 注入会失败。此外,info 端点暴露给公网时要结合 Spring Security 做访问控制,避免泄露内部系统说明。
用自定义 Banner 和启动日志展示描述
除了接口查询,启动阶段也是展示描述信息的好时机。Spring Boot 默认会在控制台打印 Banner,可以通过 spring.main.banner-mode 控制模式,也可以把描述文本写进 banner.txt。不过 banner.txt 通常用于 ASCII 艺术字,如果只是想打印一行描述,直接在 main 方法里设置自定义 Banner 更灵活。
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(OrderApplication.class);
app.setBanner((environment, sourceClass, out) -> {
out.println("订单服务");
out.println("版本: 1.0.0");
out.println("描述: 负责创建、查询和取消订单");
});
app.run(args);
}
}
如果希望描述信息与构建元数据保持一致,可以在 setBanner 的 lambda 中注入 Environment,从配置项里读取,而不是硬编码。另一种做法是用 ApplicationRunner 或 CommandLineRunner 在容器启动完成后打印描述,这样还能同时打印端口、上下文路径等运行信息,适合作为启动完成的确认日志。
最后要提醒一个常见的优先级问题:如果在 pom.xml、application.yml 和自定义 InfoContributor 里都配置了 description,最终 Actuator info 端点中会同时出现多个来源的键,而不是简单覆盖。建议团队统一一个维护入口,通常以构建元数据为准,其他位置只做读取,避免排查问题时出现相互矛盾的描述文本。

