如何使用Java 1.6 Annotation Processing执行编译时编织?

我创建了一个注释,将其应用于DTO并编写了Java 1.6样式的annotationProcessor。 我可以看到如何让annotationProcessor编写一个新的源文件,这不是我想要做的,我看不到或者找不到如何修改现有的类(理想情况下只修改字节代码)。 修改实际上是相当简单的,我希望处理器做的就是插入一个新的getter和setter,其名称来自正在处理的注释的值。

我的注释处理器看起来像这样;

@SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedAnnotationTypes({ "com.kn.salog.annotation.AggregateField" }) public class SalogDTOAnnotationProcessor extends AbstractProcessor { @Override public boolean process(final Set annotations, final RoundEnvironment roundEnv) { //do some stuff } } 

您正在寻找“Instrumentation”,这是像AspectJ那样的框架。 在这种情况下,您必须在命令行中使用“-agent”选项指定jar,然后可以过滤所有已加载的类。 在此过滤步骤中,您可以检查注释,并在将字节码加载到虚拟机之前修改它。 用于执行实际字节码修改的库包括“asm”,也可能是高级包装器“cglib”和“javassist”。 您甚至可以预编译类以生成必须由您检测的类列表,以便在开始时更快地进行过滤。

有关详细信息,请参阅java.lang.instrumentation。

按照设计,注释处理工具不允许直接修改正在处理的源代码。 但是,可以生成正在处理的类型的子类或正在处理的类型的超类 。 通过一些规划,这确实允许修改相关类型的一些效果。 我已经写了一个如何将它组合在一起的例子; 请参阅此博客条目以获取更详细的说明和一些示例代码。

你必须使用内部编译器的类 – 一些灵感:

  • AOP或APT用于覆盖超类的方法
  • RomanNumeralProcessor.java
  • Java多行字符串

但这是边缘政策。 您的程序将仅在Sun / OpenJDK上编译,并且在将来的版本中可能存在问题(内部API可能会更改)。 虽然经过编译,但它是标准的字节码,可以在任何地方运行。

顺便说一句:如果你想在Eclipse中使用它,你应该为它添加一些特殊支持,因为Eclipse使用非标准编译器。 您的设计应该更复杂,您应该为处理器添加一定程度的抽象 – 就像Lombok一样。

您必须为此扩展javac编译器,这意味着构建程序将不像常规应用程序那样可移植。 有关如何实现此目的的更多详细信息,请参阅http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/say_no_to_prope.html 。