转载

自定义注解处理器

  1. 注解处理器功能
  2. JavaPoet 创建类

步骤

1.注解库和注解类

  1. 新建 java Library 作为注解库, 名为"libmyannotation"
  2. build.gradle 配置:
// [1] 引入 java-library 插件
apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

sourceCompatibility = "7"
targetCompatibility = "7"
复制代码
  1. 新建注解类 MethodAnnotation:
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface MethodAnnotation {
}
复制代码

2. 注解处理库

  1. 再新建 Java Library 作为注解处理库,名为"libmy",此处必须选择 Java Library, 否则有些类如 AbstractProcessor 引不进来
  2. 配置 build.gradle:
apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    //[1] 自动注册注解处理器, 跟 @AutoService 有关
    implementation 'com.google.auto.service:auto-service:1.0-rc4' 
    // [2] javapoet代码生成框架来生成代码
    implementation 'com.squareup:javapoet:1.11.1' 
    
    //[3] 依赖自定义注解库
    implementation project(':libmyannotation')
    //[4] 自动注册注解处理器的处理,会在当前模块的 build 文件夹下生成 /META-INF/services/javax.annotation.processing.Processor
    annotationProcessor "com.google.auto.service:auto-service:1.0-rc4"
}

sourceCompatibility = "7"
targetCompatibility = "7"

复制代码
  1. 注解处理器类 AbstractProcessor
//[1] AutoService 注解,指定注册服务
@AutoService(Processor.class)
public class MyClass extends AbstractProcessor {
    private Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        // javac Filer
        filer = processingEnvironment.getFiler();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        // 支持的注解
        Set<String> sets = new HashSet<>();
        sets.add(MethodAnnotation.class.getCanonicalName());
        return sets;
    }

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


    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        System.out.println("这是注解 process" + set + "," + roundEnvironment);
        //这个方法会调用三次
        //1. [com.xh.libmyannotation.MethodAnnotation],[errorRaised=false, rootElements=[com.xh.testannotationprocess.TestClass, ...], processingOver=false]
        //2. [],[errorRaised=false, rootElements=[com.example.HelloWorld], processingOver=false]
        //3. [],[errorRaised=false, rootElements=[], processingOver=true]
        buildCustomClass();
        return true;
    }

    /**
     * 构建类
     */
    private void buildCustomClass() {
        //创建 main 方法
        MethodSpec main = MethodSpec.methodBuilder("main")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .returns(void.class)//返回值
                .addParameter(String[].class, "args")//参数
                .addStatement("$T.out.println($S)", System.class, "Hello World from JavaPoet!")
                .build();
        //创建类
        TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addMethod(main)
                .build();

        try {
            JavaFile javaFile = JavaFile.builder("com.example", helloWorld)
                    .addFileComment("This codes are generated automatically. Do not modify!")
                    .build();
            System.out.println("path:" + filer);
            javaFile.writeTo(filer);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
复制代码
  1. 执行模块的 clean build 命令,可以在build 文件夹下生成 /META-INF/services/javax.annotation.processing.Processor

3. app 模块进行测试

注意:Java 写的注解只能用在 Java 类上。

  1. 配置 build.gradle
dependencies {
    // 依赖注解库
    implementation project(':libmyannotation')
    //依赖注解处理器库
    annotationProcessor project(':libmy')
}
复制代码
  1. 新建测试类 Test2Class,书写方法注解,这个注解作为注解处理器生效的触发点
public class Test2Class {
    @MethodAnnotation
    public void method1(){

    }
}
复制代码
  1. 执行 clean build 命令,可以在 /build/generated/source/apt/debug/包名/ 下找到自动生成的 HelloWorld 类
// This codes are generated automatically. Do not modify!
package com.example;

import java.lang.String;
import java.lang.System;

public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello World from JavaPoet!");
  }
}

复制代码
原文  https://juejin.im/post/5d39720fe51d457778117472
正文到此结束
Loading...