使用注解强制方法签名

Enforce method signature using annotations

我编写了一个自定义注释,用于查找可通过 IoT 平台调用的方法。这是一个方法级别的注释:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DirectMethod {

    String value();

}

我在运行时查看了这个注解,要调用成功,预期的签名必须是:

@DeviceMethod("metod")
public ReturnType methodName(final String data) {...}

即 return 类型和输入参数至关重要。

当目标类型为 METHOD 时,是否有任何方法可以使注释为 "smart"?比如集成 IDE 警告等。或者我是否只需要在启动时手动处理每个注释,如果任何方法破坏了我的预期方法合同,启动过程就会失败?

是的,您可以编写注释处理器来验证您的调用,唯一的缺点是注释处理器需要传递给 javac(gradle 并且 maven 支持简单的语法来注册它们)所以有人可以只是不这样做,看不到任何 warnings/errors。

但除此之外,您需要做的就是创建特殊的注释和处理器,例如:

@SupportedAnnotationTypes("com.gotofinal.direct.DirectMethod")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class DirectAnnProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        TypeElement stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String");
        TypeElement expectedReturnType = processingEnv.getElementUtils().getTypeElement("com.gotofinal.direct.ReturnType");

        for (Element element : roundEnv.getElementsAnnotatedWith(DirectMethod.class)) {
            if (! (element instanceof ExecutableElement)) {
                processingEnv.getMessager().printMessage(Kind.ERROR, "Annotation should be on method.");
                continue;
            }
            ExecutableElement executableElement = (ExecutableElement) element;
            if (! executableElement.getReturnType().equals(expectedReturnType)) {
                processingEnv.getMessager().printMessage(Kind.ERROR, "Method should return ReturnType");
            }
            List<? extends VariableElement> parameters = executableElement.getParameters();
            if (parameters.size() != 1 && parameters.get(0).asType().equals(stringType)) {
                processingEnv.getMessager().printMessage(Kind.ERROR, "Method should have single String argument");
            }
        }
        return true; // no further processing of this annotation type
    }
}

并在META-INF/services/javax.annotation.processing.Processor文件中注册:

com.gotofinal.direct.DirectAnnProcessor

然后您可以将此类库添加到 maven/gradle 作为注释处理器,它应该会报告任何问题。在 gradle 中,必须使用 annotationProcessor "my:lib:0.1" 声明添加此类库。