繁体   English   中英

为什么 JPMS 允许注释类型作为服务

[英]Why does JPMS allow annotation types as services

在介绍 JPMS 服务时,Java 语言规范的 7.7.4 节指出“服务类型必须是类类型、接口类型或注释类型”。

我正在努力理解允许注释的意义。 我的理解是服务的 JPMS 概念是我们期望在运行时为其选择实现的东西。 看起来,为了有用,实现至少需要有可能是不同于标识所请求服务的原始类的东西。 但我相信注释不能使用“扩展”,所以这永远不会发生? 从那以后,我相信如果我尝试使用注释类型创建服务,我将不可避免地遇到这样一种情况,即服务查找可能返回的唯一内容,例如 SomeAnnotation。类将完全是 SomeAnnotation。 这似乎毫无意义,所以我必须假设我错过了一些东西。

任何人都可以阐明这一点,也许可以提供注释如何成为“服务”的示例?

您似乎错过了服务提供商的另一个补充。 在命名模块中,服务提供者可以从静态方法返回实现:

  • 如果服务提供者声明了提供者方法,则服务加载器调用该方法来获取服务提供者的实例。 提供者方法是名为“提供者”的公共静态方法,没有形式参数和可分配给服务接口或类的返回类型。

    在这种情况下,服务提供者本身不需要分配给服务的接口或类。

来自ServiceLoader

因此,以下将起作用:

module Example.Module {
    uses example.Anno;
    provides example.Anno with example.AnnoProvider;
}
package example;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
    int value();
}
package example;

@Anno(42)
public class AnnoProvider {
    public static Anno provider() {
        return AnnoProvider.class.getAnnotation(Anno.class);
    }
}
package example;

import java.util.ServiceLoader;

public class ServiceUser {
    public static void main(String[] args) {
        for(Anno a: ServiceLoader.load(Anno.class)) {
            System.out.println(a.value());
        }
    }
}

虽然在 Java 中注解接口不能显式扩展任何接口(但它总是隐式扩展java.lang.annotation.Annotation ),但它可以被实现。 即,虽然根据JLS 9.6 ,但在语法上可以编写实现注释接口的具体类 Annotation Types这样的类不代表注解类型:

注释类型的子类或子接口本身永远不是注释类型

因此,我相信最初的问题归结为“为什么有人要显式实现注释接口? ”。 这个问题已经在 SO: Use cases for implementation annotations上被问过和回答过。 那里接受的答案建议这样做是为了部分克服注释元素的值必须是常量表达式、类文字或枚举常量的限制(请参阅JLS 9.7.1. 普通注释):一个可以实现一个注释接口,用一个“注释”来“注释”实现类,该“注释”包括从配置文件、数据库等中获取的动态数据。显然,这种技术还需要对读取注释的代码进行小的更改,如实现注解接口的类实际上没有注解,而是它的实例可以用作注解的实例,就好像它是通过java.lang.Class.getAnnotationsByType检索的一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM