我有一个可以添加到METHOD
和TYPE
的注释,并在我们项目的数千个地方使用。
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE})
@Inherited
public @interface RequiredStore{
Store value();
}
是否可以仅在方法上弃用注释,同时在类型上保持不推荐使用?我希望IDE通知其他开发人员它不应再用于方法,直到我们重构所有现有用法并最终删除METHOD
部分。
如果不可能,除了仅为类型创建新注释并弃用旧注释外,还有办法处理这种情况吗?
答案 0 :(得分:5)
您可以使用注释Processor。
例如,注释及其处理器将放在其自己的.jar
文件中,并作为使用注释的源的依赖项添加。
自定义.jar
具有以下结构:
src/main/ java/com/company/annotations/ RequiredStore.java RequiredStoreProcessor.java resources/META-INF/services javax.annotation.processing.Processor
RequiredStore.java
保持原样。
RequiredStoreProcessor.java
看起来像这样:
package com.company.annotations;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("com.company.annotations.RequiredStore")
public class RequiredStoreProcessor extends AbstractProcessor {
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element element
: roundEnv.getElementsAnnotatedWith(RequiredStore.class)) {
if (element.getKind().equals(ElementKind.METHOD)) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
"Using @RequiredStore on methods has been deprecated\n"
+ "Class: " + element.getEnclosingElement() + "\n"
+ "Method: " + element.getSimpleName() + "\n");
}
}
// Other processing...
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}
javax.annotation.processing.Processor
文件允许javac
通过SPI拾取处理器,只包含
com.company.annotations.RequiredStoreProcessor
最后,将其编译为.jar
并将其添加到使用注释的类路径中。任何具有@RequiredStore
的方法都会产生编译器警告。例如,对于这个类,
package com.company.business;
import com.company.annotations.RequiredStore;
@RequiredStore
public interface Business {
@RequiredStore
public void someMethod();
}
编译器警告是这样的:
warning: Using @RequiredStore on methods has been deprecated Class: com.company.business.Business Method: someMethod
至于IDE中的指示,您可能必须编写自定义检查,不幸的是,这取决于所使用的IDE。
体面的自定义注释参考:Code Generation using Annotation Processors in the Java language
答案 1 :(得分:2)
如果你可以使用native aspectj,另一个选择就是以这种方式使用AspectJ的代码执行策略:
public aspect RequiredStoreAnnotationCheck {
declare warning: execution(@RequiredStore * *.*(..)) : "Required store annotation not appropriate for methods..";
}
如果IDE与AspectJ集成,则会将其标记为编译时检查。
行动手册中的AspectJ也有很多细节。
以下是我的博客文章之一,内容更多:http://www.java-allandsundry.com/2012/03/code-policy-enforcement-using-aspectj.html