组件化之注解处理器

一、项目结构
项目结构需要有注解工程(属于Java工程)、注解处理工程(属于Java工程),如下图所示:
在这里插入图片描述
二、APT技术简介
APT(Annotation Processing Tool) 是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,根据注解自动生成代码,如果想要自定义的注解处理器能够正常运行,必须要通过APT工具来进行处理。(总而言之,就是通过注解自动生成Java代码)

三、如何确保注解处理程序编译OK
如下图所示,ARouterProcessor.java 在META-INF 中存在对应的注册
在这里插入图片描述
四、处理程序代码编写

package com.lgj.compiler;

import com.google.auto.service.AutoService;
import com.lgj.arouter_annotations.ARouter;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;

/*
* 所有的注解写在一起,是为了框架的独立性
* 注解处理器,通过注解生成Java代码 apt技术
* 是一个背后的服务,
* */


// 对ARouter 注解的处理
@AutoService(Processor.class) // 启用服务
@SupportedAnnotationTypes({"com.lgj.arouter_annotations.ARouter"})// 需要对那个注解进行处理
@SupportedSourceVersion(SourceVersion.RELEASE_7)// 环境的版本


// 接收 安卓工程传递过来的参数
@SupportedOptions("student")
public class ARouterProcessor extends AbstractProcessor {
    // 操作Element的工具类(类,函数,属性,其实都是Element)
    private Elements elementTool;

    // type(类信息)的工具类,包含用于操作TypeMirror的工具方法
    private Types typeTool;

    // Message用来打印 日志相关信息
    private Messager messager;

    // 文件生成器, 类 资源 等,就是最终要生成的文件 是需要Filer来完成的
    private Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        elementTool = processingEnvironment.getElementUtils();
        messager = processingEnvironment.getMessager();
        filer = processingEnvironment.getFiler();
        // 把Android端,传递过来的参数,打印出来
        String value = processingEnvironment.getOptions().get("student");
        // 如果我想在注解处理器里面抛出异常 可以使用Diagnostic.Kind.ERROR
        // 正常的打印日志,采用note级别的就行
        messager.printMessage(Diagnostic.Kind.NOTE,">>>>>>>>>>>>>>>>>>>>>>>>>>> lgj :" + value);
    }

    // 在编译的时候干活,如果APP壳中没有使用任何的注解,那么这个函数不会执行
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
        messager.printMessage(Diagnostic.Kind.NOTE,">>>>>>>>>>>>>>>>>>>>>>>>>>> lgj run ...");
        /**
         模块一
         package com.example.helloworld;

         public final class HelloWorld {

         public static void main(String[] args) {
         System.out.println("Hello, JavaPoet!");
         }
         }
         */
        // 通过JavaPote 生成上面的类
        // 获取被 ARouter 注解的 "类节点信息"
        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ARouter.class);
        for (Element element : elements) {
            // Java 万物接皆对象
            // 1.方法
            MethodSpec mainMethod = MethodSpec.methodBuilder("main")
                    .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                    .returns(void.class)
                    .addParameter(String[].class,"args")
                    // 增加main方法里面的内容
                    // $T 代表类,相当于占位符,$S 代表字符串
                    .addStatement("$T.out.println($S)",System.class,"hellp JavaPoet")
                    .build();
            // 2.类
            TypeSpec testClass = TypeSpec.classBuilder("LgjTest")
                    .addMethod(mainMethod)
                    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                    .build();
            // 3.包
            JavaFile packagef = JavaFile.builder("com.xiangxue.test", testClass).build();

            // 生成文件
            try {
                packagef.writeTo(filer);
            } catch (IOException e) {
                e.printStackTrace();
                messager.printMessage(Diagnostic.Kind.NOTE, "生成Test文件时失败,异常:" + e.getMessage());
            }
        }
        return false; // false不干活了      true干完了
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值