编译时注解(转)

原文http://fucknmb.com/2017/02/07/%E7%BC%96%E8%AF%91%E6%97%B6%E6%B3%A8%E8%A7%A35%E6%AD%A5%E8%B5%B0/

新建Java Module
http://fucknmb.com/2017/02/07/%E7%BC%96%E8%AF%91%E6%97%B6%E6%B3%A8%E8%A7%A35%E6%AD%A5%E8%B5%B0/new-module.png

引入auto-service(自动生成services下文件)和javapoet(生成java文件)

compile 'com.google.auto.service:auto-service:1.0-rc2'
compile 'com.squareup:javapoet:1.8.0'

编写注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
@Inherited
public @interface Api {
    String scope();
    String name();
    String version();
}

创建AbstractProcessor实现类

重写getSupportedSourceVersion,getSupportedAnnotationTypes和process方法。注意在类上加入注解AutoService,便会自动生成META-INF下的services文件

@AutoService(Processor.class)
public class AnnotationProcessor extends AbstractProcessor {
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
    @Override
    public Set getSupportedAnnotationTypes() {
        Set supportedAnnotationTypes = new HashSet<>();
        supportedAnnotationTypes.add(Api.class.getCanonicalName());
        return supportedAnnotationTypes;
    }
    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        return false;
    }
}

实现process方法,根据注解生成对应代码

public boolean process(Set annotations, RoundEnvironment roundEnv) {
    Set elements = roundEnv.getElementsAnnotatedWith(Api.class);
    for (Element e : elements) {
        //获得对应的注解
        Api api = e.getAnnotation(Api.class);
        System.out.println("*");
        //使用javapoet开始生成代码
        TypeSpec clazz = TypeSpec.classBuilder(api.name().toUpperCase() + "Request")
                .addJavadoc("Generated request for network\n")
                .addSuperinterface(Serializable.class)
                .build();
        JavaFile javaFile = JavaFile.builder("com.funcknmb.api", clazz)
                .build();
        //生成的代码写入文件
        try {
            JavaFileObject fileObject = processingEnv.getFiler().createSourceFile("com.funcknmb.api." + api.name().toUpperCase() + "Request");
            processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating " + fileObject.toUri());
            Writer writer = fileObject.openWriter();
            javaFile.writeTo(writer);
            writer.close();
        } catch (IOException x) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, x.toString());
        }
    }
    return false;
}

总结

编写的注解以及process的实现只是做个模板,具体情况视情况而定。

你可能感兴趣的:(编译时注解(转))