Java自定义AnnotationProcessor处理自己的Annotation

Java使用Annotation Processor获取代码中的Annotation

使用Java的Annotation Processing Tool (apt)可以在编译期获取Java代码文件中的Annotation。
项目源码:https://github.com/nuptboyzhb/CustomAnnotationProcessor


Annotation的定义

如下,定义了一个MyMethodAnnotation

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface MyMethodAnnotation {
    int layoutId() default 0;
    int viewType() default 0;
    String viewHolder();
}


使用关键字@interface定义了MyMethodAnnotation,它可以保存三个值。注意,Annotation的属性

1.Retention

编译时处理的注解,它的类型是RetentionPolicy.CLASS;Retention的保留类型还有另外两种,RetentionPolicy.SOURCE和RetentionPolicy.RUNTIME。

2.Target

注解使用的目标,ElementType.METHOD表示这个注解是使用在方法上的。除了方法之外,还包括使用在成员变量上的ElementType.FIELD类型以及使用在类、接口上的ElementType.TYPE类型。


Annotation的处理AbstractProcessor

我们可以写一个自己的AnnotationProcessor,继承自AbstractProcessor,然后导出Jar包,并在Jar包的META-INF中的services目录指定相应的处理类即可。具体做法为:

实现自己的AbstractProcessor

public class CustomAnnotationProcessor extends AbstractProcessor {


private Set<String> supportedAnnotationTypes = new HashSet<String>();

@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);
    supportedAnnotationTypes.add(MyMethodAnnotation.class
            .getCanonicalName());
}

@Override
public boolean process(Set<? extends TypeElement> annotations,
        RoundEnvironment roundEnv) {
    Messager messager = processingEnv.getMessager();
    for (TypeElement typeElement : annotations) {
        for (Element element : roundEnv
                .getElementsAnnotatedWith(typeElement)) {
            String info = "### content = " + element.toString();
            messager.printMessage(Kind.NOTE, info);
            //获取Annotation
            MyMethodAnnotation myMethodAnnotation = element
                    .getAnnotation(MyMethodAnnotation.class);

            if (myMethodAnnotation != null) {
                int layoutId = myMethodAnnotation.layoutId();
                int viewType = myMethodAnnotation.viewType();
                String viewHolder = myMethodAnnotation.viewHolder();
                messager.printMessage(Kind.NOTE, "layoutId = " + layoutId
                        + ",viewType = " + viewType + ",viewHolder = "
                        + viewHolder);
            }

        }
    }
    return false;
}

@Override
public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.latestSupported();
}

@Override
public Set<String> getSupportedAnnotationTypes() {
    return supportedAnnotationTypes;
}

}


主要需要关注的点:

getSupportedAnnotationTypes方法

把需要处理的Annotation的类名,保存到一个Set中,然后返回。如果不指定对应的Annotation列表,那么process方法中将处理不到任何的Annotation。

process方法

在这里处理支持的Annotation类型。处理逻辑是:遍历所有的TypeElement的类型,然后再遍历每一个Element,然后再获得element的注解,把注解中注入的值打印出来。


Jar包的导出

Java项目的目录如下:
dir
需要在javax.annotaion.processing.Processor文件中指定对应的处理入口,比如:
conf
我们使用Eclipse将其导出成custom-annotation-process.1.0.jar包。导出之后的Jar包,反编译之后的结构为:
de_complie


编译时获取Annotation

比如,我们需要编译如下代码:

public class HelloMain {

  @MyMethodAnnotation(layoutId = 100,viewType = 1,viewHolder = "com.example.test")
  public void fun(){

  }
}


根据之前我们写的CustomAnnotationProcessor可知,我们可以获取fun方法的注解,并能够将注解内的值取出。
使用javac命令,-cp参数,对上述的HelloMain.java进行编译处理。在windows的cmd下的命令如下:

dir /s /B *.java > javas.txt
javac -cp custom-annotation-process.1.0.jar @javas.txt


首先将Java文件的路径写入到javas.txt文件中,然后使用javac编译文件。在cmd中打印结果如下:
cmd

当然,除了直接使用javac命令之外,在Eclipse、Maven中也可以配置。在此,不在赘述。

参考

[1] Annotation Processor配置
[2] Annotation实战

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java自定义注解接口的实现是为了提供一种元数据的形式,用于在编译时或运行时对代码进行标记和定制。以下是如何创建和使用自定义注解的步骤: 1. **定义注解接口**: 创建一个新的注解接口,通常使用 `@interface` 关键字,例如: ```java @Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation { String value() default ""; int param() default 0; boolean flag() default false; } ``` 这里定义了一个名为 `MyCustomAnnotation` 的注解,它有三个属性:`value`、`param` 和 `flag`。 2. **在类上应用注解**: 在类、方法、变量等上使用 `@MyCustomAnnotation` 标记,例如: ```java @MyCustomAnnotation(value = "customValue", param = 123, flag = true) public class MyClass { // ... } ``` 3. **处理注解**: - 如果在编译期间(`RetentionPolicy.SOURCE` 或 ` RetentionPolicy.CLASS`),可以使用 `javac` 编译器插件访问注解信息。 - 如果在运行期间(`RetentionPolicy.RUNTIME`),可以使用反射 API(如 `java.lang.reflect.Annotation`)获取和处理注解。 4. **编写注解处理器**(可选): 如果你想在编译期间做更多的处理,可以创建一个注解处理器类,实现 `javax.annotation.processing.Processor` 接口。这个处理器会在编译时被调用,处理你定义的注解。 相关问题: 1. 如何查看Java源码中的注解信息? 2. 注解处理器的主要用途是什么? 3. 如何在运行时动态获取类上的自定义注解?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值