向Java类添加编程注释

向Java类添加编程注释,java,compiler-construction,annotations,bytecode-manipulation,Java,Compiler Construction,Annotations,Bytecode Manipulation,用法示例: 我想在类字段上添加一个自定义注释@MyContainer,然后在所有此类字段上自动添加相关的Hibernate注释(取决于字段类型和属性)。 另外,我需要将JAXB XmlType注释添加到类中,并将类型名称基于类名。 此外,我还想根据字段类型等向字段添加注释。 所有添加的注释都应该在运行时可用(以便hibernate/JAXB可以找到它们)。 我知道以下选项: 预处理类源(错误选项) 使用javax.annotation.Processing API编译期间的处理 使用Java A

用法示例:
我想在类字段上添加一个自定义注释@MyContainer,然后在所有此类字段上自动添加相关的Hibernate注释(取决于字段类型和属性)。
另外,我需要将JAXB XmlType注释添加到类中,并将类型名称基于类名。
此外,我还想根据字段类型等向字段添加注释。 所有添加的注释都应该在运行时可用(以便hibernate/JAXB可以找到它们)。
我知道以下选项:

  • 预处理类源(错误选项)
  • 使用javax.annotation.Processing API编译期间的处理
  • 使用Java Assist等工具进行编译后操作
  • 使用java.lang.instrument API加载类期间的操作
  • 使用AspectJ进行操作(功能不够强大)
  • 我的主要目标是:

  • 保持类和源之间的同步以进行调试
  • 支持从Maven和IDE(Eclipse/Intellij)工作

  • 如果已经做过这类工作的人能够推荐完成这类任务的最佳方法(可能还有潜在的陷阱),我将不胜感激。

    我认为预处理类源应该是您首选的方法。这使您能够使源代码与编译的类同步,这有利于调试,正如您所提到的。但它也有利于版本控制,因为您可以签入生成的注释。如果在编译过程中运行工具,跟踪工具中的问题也会困难得多。在生成源代码阶段运行代码生成时,IDE支持也应该没有问题

    编辑: 快速搜索产生了一些关于编程java源代码修改的信息
    或但这可能值得更多的研究或是它本身的一个问题。

    我想建议另一种方法。因为我可能需要编写自己的工具,所以您也可以尝试一种更简单的解决方案。我希望您正在对类进行单元测试,您可以为此类的每个单元测试实现一个基类。在这个基类中有一个测试方法,它检查用
    @MyContainer
    注释的每个字段是否也有所需的hibernate注释


    我们基本上做了同样的事情,不是针对注释,而是针对字段的可序列化性,并且使用这种方法运行得非常好。

    为了让它在IDE、命令行构建和运行时最透明地工作,选项1(使用APT)和选项5(使用AspectJ)将为您提供最佳选择

    对于选项1,您必须实现自己的注释处理器,该处理器将根据您自己的@MyContainer注释的存在注入额外的注释。下面是一个使用此方法的示例

    对于选项5,您可以简单地使用。大概是这样的:

    declare @field : * ((@*..MyContainer *)).*(..) : @OtherAnnotation();
    

    Spring的Roo工具广泛使用选项5,我当然不能说它不够强大。

    上面提到的替代方案很少,而且每个都有其优点和缺点。这就是为什么我认为上述问题没有一个真正“正确”的答案。我的目的是从社区和过去做过这类事情并有经验的人那里获得投入。就我个人而言,我选择了与Javassist一起使用。通过这种方式,类在运行时被扩展(尽管相同的工具可以用于编译后处理)。好在代理可以从JVM内部加载,这避免了处理所有命令行。如果能听到其他选择,那将是一件非常棒的事情。
    谢谢,

    Avner

    这里是一个定义自定义注释的代码示例。此@TesterInfo应用于类级别,存储测试人员详细信息。这显示了返回类型的不同用法–枚举、数组和字符串

    package com.mkyong.test.core;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE) //on class level
    public @interface TesterInfo {
    
        public enum Priority {
           LOW, MEDIUM, HIGH
        }
    
        Priority priority() default Priority.MEDIUM;
    
        String[] tags() default "";
    
        String createdBy() default "Mkyong";
    
        String lastModified() default "03/01/2014";
    
    }
    

    不生成注释,而是生成可由hibernate配置加载的hibernate映射XML文件(hbm.XML)怎么样?谢谢,这是个好主意,但我更喜欢我的示例中的注释选项,因为我还需要生成JAXB注释(将来可能还会生成其他注释)。谢谢您的回答。您能否提供有关解决方案的更多信息,例如可以使用哪个工具来分析源代码并对其进行操作?缺点是源代码中充满了低级注释,而且不太清晰(我想添加注释只是为了运行时),您应该考虑使用当前类的接口并尽可能地将注释隐藏到实现中。您可以将注释和注释参数基于类/方法/成员信息建立吗?例如,我需要检查容器数据类型,并在几个可能的hibernate注释之间进行选择。另外,我需要根据字段名等为hibernate注释生成列名。。。