【问题标题】:Is it possible to create an annotation bundle in java (i.e. an annotation that applies other annotations)?是否可以在 java 中创建注释包(即应用其他注释的注释)?
【发布时间】:2020-12-17 00:15:08
【问题描述】:

假设以下代码在代码库中经常出现:

// old wet code
@AnnotationA
@AnnotationB
@AnnotationC
class SomeClass {
   // ...
}

是否可以创建一个注释AnnotationBundle 应用其他注释(A、B、C)并生成相同的功能?这只会用于 DRY 代码库,并且不会意外忘记类上的单个注释。

// new DRY code
@AnnotationBundle
class SomeClass {
   // ...
}

【问题讨论】:

  • 这对于结合 lombok 和 Spring 注释很有用,例如RequiredArgsConstructor + Slf4j + Service

标签: java spring annotations aop lombok


【解决方案1】:

简答

不,你不能。 Java 中没有元注释的概念。

备选方案 1:Spring 注释

有人提到了 Spring 元注释。是的,在 Spring 中你可以做到这一点,但这只是因为 Spring 实现了一些非常令人印象深刻的内部机制,包括反射和其他机制,以实现这个概念。所以

  • 要么使用 Spring 并依赖其功能,
  • 或者您重建类似的东西并确保您自己的应用程序使用您正在构建的框架
  • 或者您提取 Spring 注释内容并在 Spring 之外使用它。

我不久前做了后者作为手指练习,因为我想看看是否有可能提取它。这很困难,因为它与其他 Spring 的东西纠缠得很深,但最终我还是做到了。

结果是 here,一个可在 Spring 之外使用的独立版本的 Spring 注解实用程序。如果您阅读自述文件,您可以了解我是如何做到的,因为我将其记录为未来类似提取的模板。实际上,我从未使用过自己的独立 Spring 注释实用程序,但我邀请您这样做。 Spring 可以用注解做更多的事情,例如检查类实现的接口上是否有注释,超类方法上的注释等。这非常强大,并解释了为什么 Spring 可以实现一些开箱即用的 JRE 不可能实现的基于注释的东西。例如。 JDK 没有继承注解的概念,除了(可选)从超类到子类,但不是从接口到类,也不是从方法到覆盖方法。

您可以克隆并构建我的 GitHub 存储库,看看它是否可以帮助您做您想做的事情。但它不会自己神奇地发生,你必须调用相应的方法才能收集到这样的信息。

备选方案 2:AspectJ

作为替代方案,您可以使用 AspectJ(我说的是真正的 AspectJ,而不是 Spring AOP)并使用 ITD(类型间定义),例如使类实现接口或在类型上声明注释。通过这种方式,您可以实现模拟元注释的方面。方面会处理所有事情,应用程序不需要知道它。不过,我不确定你是否想学习 AOP 来做到这一点。

【讨论】:

  • 感谢您的回答!我知道一些 AOP,但我假设注释可以在运行时工作,但在开发期间不显示生成的方法等(例如,lombok 插件不会通过 IntelliJ 中的 AspectJ 检测到注释)。
【解决方案2】:

通过伪造元注释(例如Spring MVC - Meta Annotations、What Are Meta-Annotations in Java?)),这在 Java 中看起来在技术上是可行的。

但并非所有注解都如此——例如,lombok 还不允许这样做,并将注解限制为类类型(而不是@interface)。

【讨论】:

    猜你喜欢
    • 2019-02-08
    • 2010-10-15
    • 2021-12-24
    • 1970-01-01
    • 2016-02-04
    • 2019-11-08
    • 2014-10-08
    • 2015-04-30
    • 2013-11-03
    相关资源
    最近更新 更多