ButterKnife依赖注入框架源码解析

18 篇文章 0 订阅

BuffterKnife 采用 注解+ APT技术
APT:Annotation Processor tool 注解处理器,是javac的一个工具,每个处理器都是继承于AbstractProcessor

注解处理器是运行在自己的java虚拟机中

APT如何生成字节码文件:
在这里插入图片描述

Annotation Processing 不能加入或删除java方法

APT整个流程

    1. 声明的注解等待生命周期为CLASS
    1. 继承AbstractProcessor类
    1. 再调用AbstractProcessor 的process方法

AbstractProcessor.java

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.annotation.processing;

import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

public abstract class AbstractProcessor implements Processor {
    protected ProcessingEnvironment processingEnv;
    private boolean initialized = false;

    protected AbstractProcessor() {
    }

    public Set<String> getSupportedOptions() {
        SupportedOptions so = (SupportedOptions)this.getClass().getAnnotation(SupportedOptions.class);
        return so == null ? Collections.emptySet() : arrayToSet(so.value(), false);
    }

    public Set<String> getSupportedAnnotationTypes() {  // 返回所支持注解的类型
        SupportedAnnotationTypes sat = (SupportedAnnotationTypes)this.getClass().getAnnotation(SupportedAnnotationTypes.class);
        boolean initialized = this.isInitialized();
        if (sat == null) {
            if (initialized) {
                this.processingEnv.getMessager().printMessage(Kind.WARNING, "No SupportedAnnotationTypes annotation found on " + this.getClass().getName() + ", returning an empty set.");
            }

            return Collections.emptySet();
        } else {
            boolean stripModulePrefixes = initialized && this.processingEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_8) <= 0;
            return arrayToSet(sat.value(), stripModulePrefixes);
        }
    }

    public SourceVersion getSupportedSourceVersion() {  //用来指定所使用的java版本
        SupportedSourceVersion ssv = (SupportedSourceVersion)this.getClass().getAnnotation(SupportedSourceVersion.class);
        SourceVersion sv = null;
        if (ssv == null) {
            sv = SourceVersion.RELEASE_6;
            if (this.isInitialized()) {
                Messager var10000 = this.processingEnv.getMessager();
                Kind var10001 = Kind.WARNING;
                String var10002 = this.getClass().getName();
                var10000.printMessage(var10001, "No SupportedSourceVersion annotation found on " + var10002 + ", returning " + sv + ".");
            }
        } else {
            sv = ssv.value();
        }

        return sv;
    }

    public synchronized void init(ProcessingEnvironment processingEnv) {  // 初始化工作
        if (this.initialized) {
            throw new IllegalStateException("Cannot call init more than once.");
        } else {
            Objects.requireNonNull(processingEnv, "Tool provided null ProcessingEnvironment");
            this.processingEnv = processingEnv;
            this.initialized = true;
        }
    }

    public abstract boolean process(Set<? extends TypeElement> var1, RoundEnvironment var2);  // process相对于main函数,即方法的入口,在process方法中可以完成扫描、评估、处理注解等等代码。process方法最后会生成所需要的java代码

    public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) {
        return Collections.emptyList();
    }

    protected synchronized boolean isInitialized() {
        return this.initialized;
    }

    private static Set<String> arrayToSet(String[] array, boolean stripModulePrefixes) {
        assert array != null;

        Set<String> set = new HashSet(array.length);
        String[] var3 = array;
        int var4 = array.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String s = var3[var5];
            if (stripModulePrefixes) {
                int index = s.indexOf(47);
                if (index != -1) {
                    s = s.substring(index + 1);
                }
            }

            set.add(s);
        }

        return Collections.unmodifiableSet(set);
    }
}

ProcessingEnvironment.java

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.annotation.processing;

import java.util.Locale;
import java.util.Map;
import javax.lang.model.SourceVersion;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

public interface ProcessingEnvironment {
    Map<String, String> getOptions();

    Messager getMessager();

    Filer getFiler();  //用于创建文件

    Elements getElementUtils();  //用来处理Element的工具类,Element是指在注解处理过程中扫描的所有java源文件,可以把这个源文件想象成Element的全部,而源代码中每个独立的部分就可以认作为特定类型的Element

    Types getTypeUtils();  //TypeElement代表Element的类型, Types是用于获取源代码类型的信息

    SourceVersion getSourceVersion();

    Locale getLocale();
}

ButterKnife的工作原理

  1. 编译的时候扫描注解,并做相应的处理,生成java代码,生成Java代码是调用 javapoet 库生成的
  2. 调用ButterKnife.bind(this);方法的时候,将ID与对应的上下文绑定在一起
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值