last modified by zhoutianju , 2023-06-02 00:54:42
编译期常量替换
背景
Java 中运行时变量赋值或修改很灵活,有很多方式可以实现(例如:property 注入等),但有些情况必须要在编译期替换(类似 C 语言的预编译宏)就稍微麻烦点,例如下面这个场景:
注解的属性值需要根据不同环境使用不同的值,由于注解中的属性值必须是 final 的常量,因此没法通过任何运行时的手段赋值或修改
@Table(name = "xxx") // 希望 dev 环境使用 "offline"、prod 环境使用 "online"
class Demo {
}
解决方案
使用 Maven 插件 templating-maven-plugin
代码结构
.
├── pom.xml
└── src
└── main
├── java
│ └── priv
│ └── zhoutj
│ └── demo
│ ├── Demo.java
│ ├── Main.java
│ └── annotation
│ └── Foo.java
├── java-dev # dev 环境编译时使用
│ └── priv
│ └── zhoutj
│ └── demo
│ └── EnvConstant.java
└── java-prod # prod 环境编译时使用
└── priv
└── zhoutj
└── demo
└── EnvConstant.java
src/main/java/priv/zhoutj/demo/Demo.java
@Foo(name = EnvConstant.VALUE)
public class Demo {
}
src/main/java-dev/priv/zhoutj/demo/EnvConstant.java
public class EnvConstant {
public static final String VALUE = "offline";
}
src/main/java-prod/priv/zhoutj/demo/EnvConstant.java
public class EnvConstant {
public static final String VALUE = "online";
}
pom.xml
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>priv.zhoutj.demo</groupId>
<artifactId>demo-compile-time-constant-replace</artifactId>
<version>1.0.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<sourceDirectory>${basedir}/src/main/java-${profiles.active}</sourceDirectory>
<outputDirectory>${project.build.directory}/java-templates-generated-sources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
</profile>
</profiles>
</project>
IDEA 环境说明
IDEA 环境下需要将 src/main/java-prod 或 src/main/java-dev 其中一个加入到 source 根目录集合中,才能在 IDEA 中 run/debug
可参考:https://www.jetbrains.com/help/idea/content-roots.html#adding_content_root
代码参考
https://github.com/zhoutianju/demo-compile-time-constant-replace
Copyright © 2023 zhoutianju.
All rights reserved.
All rights reserved.