我如何根据注释自动生成带有静态成员的 class(类似于 Android 的 R)class
How can I auto generate a class with static members based on annotations (similar to Android's R) class
假设我有这个:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Config {
}
@Config
public class ConfigA {
public static final String FOO_A = "A";
}
@Config
public class ConfigB {
public static final String FOO_B = "B";
public static final String SOMETHING_ELSE = "SE";
}
我想自动生成如下所示的 class:
public class Result {
public static final String FOO_A = "A";
public static final String FOO_B = "B";
public static final String SOMETHING_ELSE = "SE";
}
忽略发生冲突的可能性我该如何实现?
最终目标是根据构建 type/flavour 使用 Gradle 自动生成结果,因为我正在使用 Eclipse 创建一个生成结果的构建器,以便能够使用源中的成员. (就像 Android 项目中的 R 文件是从 XML 文件生成的,但我不想使用 XML)
我会执行以下操作:
- 创建一个单独的项目(例如,命名为
codegen
)以包含 class 生成逻辑。在那里,我会使用 Reflections to scan for classes that are annotated with @Config
, add all their members to a list, and eventually output a class with those members using Velocity 或类似的模板库。
- 将您的
@Config
注释和您要注释的 class 放入他们自己的 Gradle 项目中,例如命名为 config
.
- 在您的 build.gradle 文件中,创建一个任务(例如,
processConfig
)在从 #2 生成的 classes 上运行模板工具。
- 让 Gradle 项目依赖
processConfig
使用模板化输出(例如,命名为 solution
),并将其输出添加到自定义 SourceSet。
只要您正确配置了源集,并确保主源集依赖于您的中间源集,solution
构建的其余部分就应该可以正常工作。
或者,还有更多涉及使用 ASM 或 cglib 直接生成字节码的方法也可以。
假设我有这个:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Config {
}
@Config
public class ConfigA {
public static final String FOO_A = "A";
}
@Config
public class ConfigB {
public static final String FOO_B = "B";
public static final String SOMETHING_ELSE = "SE";
}
我想自动生成如下所示的 class:
public class Result {
public static final String FOO_A = "A";
public static final String FOO_B = "B";
public static final String SOMETHING_ELSE = "SE";
}
忽略发生冲突的可能性我该如何实现?
最终目标是根据构建 type/flavour 使用 Gradle 自动生成结果,因为我正在使用 Eclipse 创建一个生成结果的构建器,以便能够使用源中的成员. (就像 Android 项目中的 R 文件是从 XML 文件生成的,但我不想使用 XML)
我会执行以下操作:
- 创建一个单独的项目(例如,命名为
codegen
)以包含 class 生成逻辑。在那里,我会使用 Reflections to scan for classes that are annotated with@Config
, add all their members to a list, and eventually output a class with those members using Velocity 或类似的模板库。 - 将您的
@Config
注释和您要注释的 class 放入他们自己的 Gradle 项目中,例如命名为config
. - 在您的 build.gradle 文件中,创建一个任务(例如,
processConfig
)在从 #2 生成的 classes 上运行模板工具。 - 让 Gradle 项目依赖
processConfig
使用模板化输出(例如,命名为solution
),并将其输出添加到自定义 SourceSet。
只要您正确配置了源集,并确保主源集依赖于您的中间源集,solution
构建的其余部分就应该可以正常工作。
或者,还有更多涉及使用 ASM 或 cglib 直接生成字节码的方法也可以。