
本文介绍如何使用 openrewrite 内置的 `replaceconstantwithanotherconstant` 配方,实现跨包、跨名称的静态常量(如 `application_json` → `application_json_value`)全自动替换,同时更新对应静态导入语句。
在 Java 项目迁移(例如从 JAX-RS 迁移到 Spring Web)过程中,常需将旧框架的静态常量(如 javax.ws.rs.core.MediaType.APPLICATION_JSON)替换为新框架中语义等价但命名/路径不同的常量(如 org.springframework.http.MediaType.APPLICATION_JSON_VALUE)。仅修改类型(如用 ChangeType)无法处理常量名差异,也无法自动同步更新 import static 语句——这正是 ReplaceConstantWithAnotherConstant 配方的设计目标。
该配方自 OpenRewrite v8.23.0 起正式支持(PR #3037),不仅能精准定位并替换所有字面量引用(含注解、方法调用、赋值等上下文),还会智能修正或添加对应的 static import,移除已失效的旧静态导入,确保编译通过且语义一致。
✅ 使用方式(YAML 配方配置)
在 rewrite.yml 中定义如下配方:
type: specs.openrewrite.org/v1beta/recipe
name: com.example.migration.ReplaceJaxRsToSpringMediaType
displayName: 将 JAX-RS MediaType 常量迁移为 Spring MediaType.VALUE 形式
recipeList:
- org.openrewrite.java.ReplaceConstantWithAnotherConstant:
existingFullyQualifiedConstantName: javax.ws.rs.core.MediaType.APPLICATION_JSON
fullyQualifiedConstantName: org.springframework.http.MediaType.APPLICATION_JSON_VALUE? 关键参数说明: existingFullyQualifiedConstantName:原始常量的完整限定名(含包名+类名+字段名),必须精确匹配; fullyQualifiedConstantName:目标常量的完整限定名,OpenRewrite 将据此生成新 import static 并替换所有引用。
? 效果验证
对原始代码:
import javax.ws.rs.*;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
class ControllerClass {
@Produces(APPLICATION_JSON)
public String getHelloWorldJSON(String name) {
return "{}";
}
}执行后自动变为:
import javax.ws.rs.*;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
class ControllerClass {
@Produces(APPLICATION_JSON_VALUE)
public String getHelloWorldJSON(String name) {
return "{}";
}
}✅ 静态导入已更新
✅ 注解内引用已替换
✅ 原 import static javax.ws.rs.core.MediaType.APPLICATION_JSON 已被自动移除
⚠️ 注意事项
- 该配方不支持通配符匹配(如 *.APPLICATION_JSON),每个常量映射需单独声明;
- 若存在多个待迁移常量(如 TEXT_PLAIN, APPLICATION_XML),需在 recipeList 中逐条列出对应 ReplaceConstantWithAnotherConstant 实例;
- 确保目标常量(如 APPLICATION_JSON_VALUE)在运行时类路径中可访问,否则编译可能失败;
- 建议搭配 rewrite-maven-plugin 或 rewrite-gradle-plugin 执行,并启用 dryRun = true 先预览变更。
通过该方案,你可将常量迁移无缝集成至大型重构流水线中,显著提升跨框架迁移的可靠性与可维护性。










