【问题标题】:How do I use Annotation Processing API in runtime?如何在运行时使用注解处理 API?
【发布时间】:2012-04-20 06:47:10
【问题描述】:

我已经并遵循了 Internet 上的几个注释处理工具 (APT) 指南(例如 12),并设法让它在编译器/构建时运行,甚至在 Eclipse 中运行。

有没有一种方法可以在运行时使用 APT 来使用我的注释获取类型(类)列表。

我写了类似的东西:

@SupportedAnnotationTypes("com.domain.MyAnnotation")
public class MyAbstractProcessor extends AbstractProcessor {

    public static Map<Element, MyAnnotation> patches = new HashMap<Element, MyAnnotation>();

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnvironment) {

        // Get all classes that has the annotation
        Set<? extends Element> classElements = roundEnvironment.getElementsAnnotatedWith(MyAnnotation.class);

        // For each class that has the annotation
        for (final Element classElement : classElements) {

            patches.put(classElement, annotation);

因此 MyAbstractProcessor.patches 将使用注释填充类列表。一个崇高的想法,除了这个 APT 在构建时执行而不是运行时的缺陷。

甚至可以在运行时使用 APT 吗?

还是我使用了错误的框架来获得我想要的东西?

【问题讨论】:

    标签: java annotations apt


    【解决方案1】:

    您可以在运行时使用反射访问注释 - getAnnotations

    要使用您的注解获取类列表(在您的类路径中),您可以在运行时遍历所有类,测试它们是否具有该注解。

    或者 - 在构建时 - 您可以使用类列表构建一个类。

    【讨论】:

    • “或者 - 在构建时 - 您可以使用类列表构建一个类。” - 你的意思是,输出到应用程序在运行时读取的文件?
    • 是的,使用processingEnv.getFiler().createSourceFile(qualifiedName).openWriter() 并将补丁的内容写入qualifedName 类中的静态变量。当然,您必须编写所有必需的类样板 `public class simpleName { private static final Map patch = new Map { contents of patch } ...
    • 哇,createSourceFile 很棒。我不知道这是可能的。谢谢:-)
    • 问题出现了,假设我们编写了一些带有反射的运行时注释处理器,并展示了我们的整个库,其中包括我们的注释,而其他一些人在他们自己的项目中使用我们的库。他在他的代码中使用我们的注解,当我们的注解运行时处理方法被调用时,由谁调用?运行时处理器应该有一些入口点,对吧?还是我遗漏了一些关键点?
    • @mostafa.S Spring Boot 就是一个例子。我相信他们使用反射在运行时进行注释处理。我在自己的项目中使用 Spring Boot。我在我的代码中使用 Spring Boot 注释(例如,AT Service、AT Autowired、AT RestController 等)。 Spring Boot 应用程序是入口点。你是对的,总有一些切入点。
    【解决方案2】:

    您是否使用 RetentionPolicy 指定您的注解在运行时可用? 如果不是,你需要在你的上使用@Retention 注解。

    @Retention(RetentionPolicy.RUNTIME)
    
    public @interface MyAnnotation {
        String[] parameters();
        String[] exceptions();
    }
    

    【讨论】:

    • 是的,我做到了。 SOURCE 和 RUNTIME :-)
    • 通常情况下,它应该可以使用此保留策略。如果它不适用于 APT,您可以尝试 JSR 269 (Pluggable Annotations Processing)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 2014-10-26
    相关资源
    最近更新 更多