7

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

  1. 预处理类源(坏选项)
  2. 在编译期间使用 javax.annotation.processing API 进行处理
  3. 使用 Java Assist 等工具进行编译后操作
  4. 使用 java.lang.instrument API 在类加载期间进行操作
  5. 用 AspectJ 做(不够强大)

我的主要目标是:

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

如果已经做过此类事情的人可以推荐此类任务的最佳方法(也许还有潜在的陷阱),我将不胜感激。

4

5 回答 5

1

这是定义自定义注释的代码示例。此@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";

}
于 2015-07-08T22:19:43.230 回答
0

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

对于选项 1,您必须实现自己的注释处理器,该处理器将根据您自己的 @MyContainer 注释的存在注入额外的注释。这是用于类似事物的这种方法的示例。

对于选项 5,您可以简单地使用注释声明。像这样的东西:

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

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

于 2012-07-23T18:19:49.280 回答
0

我认为预处理类源应该是您的首选方式。这使您能够使您的源代码与编译的类同步,这对于您提到的调试很有好处。但它也有利于版本控制,因为您可以签入那些生成的注释。如果在编译期间运行它,那么在您的工具中跟踪问题也会变得更加困难。在 generate-sources 阶段运行代码生成时,IDE 支持也应该没有问题。

编辑:快速搜索产生了一些关于使用 eclipse jdtnetbeans 中的某些东西进行编程 java 源代码修改的信息 。但这可能值得进行更多研究或本身的问题。

于 2012-07-22T20:13:06.650 回答
0

我想就此提出另一种方法。由于我的第一个答案可能涉及编写自己的工具,您也可以尝试一个更简单的解决方案。正如我希望您对您的类进行单元测试一样,您可以为此类的每个单元测试实现一个基类。在这个基类中有一个测试方法,它检查每个带有注释的字段是否@MyContainer也具有所需的休眠注释。

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

于 2012-07-23T07:11:53.367 回答
0

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

于 2012-07-27T09:27:47.400 回答