你能在一个方法上要求至少一个特定类型的Spring Annotation吗?



我们有两种类型的注释。一个指定Authz检查,另一个显式指定不:@AuthZCheck(type=…)和@NoAuthZCheck。

是否有一种方法可以要求至少一个方法上的这些注释,否则会导致某种(最好)编译时错误?

// this is ok
@AuthZCheck
public void getSensitiveInfo()
// this is ok
@NoAuthZCheck
public void getPublicInfo()
// this is NOT ok
public void getInfo()

Edit1澄清一下,这与其说是一个功能问题,不如说是一个政策问题。我们允许其他开发人员编写这些方法,我们希望他们仔细考虑需要哪种类型的AuthZ检查。其中一些确实不需要AuthZ检查,要么是因为它是一个公共API,要么是因为后端服务自己完成了AuthZ验证。但是我们发现有些开发者在没有考虑的情况下就忽略了AuthZ检查。他们可能复制粘贴了另一个不需要它的方法,而没有考虑甚至不知道AuthZ检查功能。我们希望结束这种做法,并要求一个显式的AuthZ注释,即使是在不需要AuthZ的情况下。

您可以使用注释来完成此操作处理器。模板实现如下:

package processing;
import java.util.Collections;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
public class CheckAuthZ implements Processor {
private ProcessingEnvironment processingEnv = null;
@Override
public Set<String> getSupportedOptions() { return Collections.emptySet(); }
@Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton("*");
}
@Override
public SourceVersion getSupportedSourceVersion() {
SourceVersion[] values = SourceVersion.values();
return values[values.length - 1];
}
@Override
public void init(ProcessingEnvironment processingEnv) {
this.processingEnv = processingEnv;
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
/*
* Called for every TypeElement
*/
}
}

您需要充实process()方法的逻辑。我已经重复通过并检查公共方法是否存在至少一个注释。

import ...AuthZCheck;
import ...NoAuthZCheck;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.util.ElementFilter.methodsIn;
import static javax.tools.Diagnostic.Kind.ERROR;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement type : set) {
for (ExecutableElement method : methodsIn(type.getEnclosedElements())) {
if (method.getModifiers().contains(PUBLIC)) {
if (! (method.getAnnotation(AuthZCheck.class) != null || method.getAnnotation(NoAuthZCheck.class) != null)) {
processingEnv.getMessager()
.printMessage(ERROR, "No annotation");
}
}
}
}
}

(如果希望继续编译,请使用WARNING而不是ERROR)

并作为服务提供者打包到JAR中。META-INF/services/javax.annotation.processing.Processor必须包含:

processing.CheckAuthZ

将该JAR包含在编译路径中以进行强制/检测。

最新更新