栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Eventbus注解解析器源码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Eventbus注解解析器源码分析

一.注解解析器配置

1.annotationProcessor project(':eventbus-annotation-processor')

2.annotationProcessorOptions {
                arguments = [eventBusIndex: 'org.greenrobot.eventbusperf.MyEventBusIndex']
            }

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
    }
}

apply plugin: 'com.android.application'

dependencies {
    implementation project(':eventbus')
    annotationProcessor project(':eventbus-annotation-processor')
    implementation 'com.squareup:otto:1.3.8'
}

android {
    compileSdkVersion _compileSdkVersion

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            res.srcDirs = ['res']
        }
    }

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 26
        versionCode 1
        versionName "2.0.0"
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [eventBusIndex: 'org.greenrobot.eventbusperf.MyEventBusIndex']
            }
        }
    }
}
二.源码分析

1.生成的类

package org.greenrobot.eventbusperf;

import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;
import org.greenrobot.eventbus.meta.SubscriberMethodInfo;
import org.greenrobot.eventbus.meta.SubscriberInfo;
import org.greenrobot.eventbus.meta.SubscriberInfoIndex;

import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.Map;


public class MyEventBusIndex implements SubscriberInfoIndex {
    private static final Map, SubscriberInfo> SUBSCRIBER_INDEX;

    static {
        SUBSCRIBER_INDEX = new HashMap, SubscriberInfo>();

        putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscriberClassEventBusAsync.class,
                true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEventAsync", TestEvent.class, ThreadMode.ASYNC),
        }));

        putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusMainOrdered.class,
                true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEvent", TestEvent.class, ThreadMode.MAIN_ORDERED),
        }));

        putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusMain.class,
                true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEventMainThread", TestEvent.class, ThreadMode.MAIN),
        }));

        putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusBackground.class,
                true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEventBackgroundThread", TestEvent.class, ThreadMode.BACKGROUND),
        }));

        putIndex(new SimpleSubscriberInfo(TestRunnerActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEventMainThread", TestFinishedEvent.class, ThreadMode.MAIN),
        }));

        putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.SubscribeClassEventBusDefault.class,
                true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEvent", TestEvent.class),
        }));

    }

    private static void putIndex(SubscriberInfo info) {
        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
    }

    @Override
    public SubscriberInfo getSubscriberInfo(Class subscriberClass) {
        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
        if (info != null) {
            return info;
        } else {
            return null;
        }
    }
}

2.注解处理器核心代码

继承自AbstractProcessor,重写process方法,3步,取出所有订阅者信息,检查订阅者信息,创建文件

@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")//Subscribe的注解
@SupportedOptions(value = {"eventBusIndex", "verbose"})//参数,可配置参数
@IncrementalAnnotationProcessor(AGGREGATING)//聚合,总计;合计aggregating
public class EventBusAnnotationProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set annotations, RoundEnvironment env) {
            String index = processingEnv.getOptions().get(OPTION_EVENT_BUS_INDEX);
            verbose = Boolean.parseBoolean(processingEnv.getOptions().get(OPTION_VERBOSE));
            int lastPeriod = index.lastIndexOf('.');
            //package名字
            String indexPackage = lastPeriod != -1 ? index.substring(0, lastPeriod) : null;
        
            // 取出所有订阅者信息
            collectSubscribers(annotations, env, messager);
            // 检查订阅者信息
            checkForSubscribersToSkip(messager, indexPackage);

            if (!methodsByClass.isEmpty()) {
                // 查找到的注解的方法不为空,生成Java文件
                createInfoIndexFile(index);
            } 
        return true;
    } 
}

代码注释

package org.greenrobot.eventbus.annotationprocessor;

import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

import de.greenrobot.common.ListMap;

import static net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.AGGREGATING;


@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")//Subscribe的注解
@SupportedOptions(value = {"eventBusIndex", "verbose"})//参数,可配置参数
@IncrementalAnnotationProcessor(AGGREGATING)//聚合,总计;合计aggregating
public class EventBusAnnotationProcessor extends AbstractProcessor {
    //region 参数
    //    annotationProcessorOptions {
//        arguments = [eventBusIndex: 'org.greenrobot.eventbusperf.MyEventBusIndex']
//    }
    ///Users/admin/StudioProjects/EventBus/EventBusPerformance/build/generated/ap_generated_sources/debug/out/org/greenrobot/eventbusperf/MyEventBusIndex.java
    public static final String OPTION_EVENT_BUS_INDEX = "eventBusIndex";//参数,文件位置
    public static final String OPTION_VERBOSE = "verbose";//冗长的,打印log

    
    // 自定义的数据结构,保存`>`类型数据;这里的key是订阅类,List是方法
    private final ListMap methodsByClass = new ListMap<>();
    // 保存不合法的元素,这里的key是订阅类
    private final Set classesToSkip = new HashSet<>();

    private boolean writerRoundDone;//writerRoundDone,用于标记多次进入process异常情况
    private int round;//round过程,用于标记多次进入process异常情况
    private boolean verbose;//是否打印所有log
    //endregion

    @Override
    public boolean process(Set annotations, RoundEnvironment env) {//TypeElement RoundEnvironment
        Messager messager = processingEnv.getMessager();
        try {
            String index = processingEnv.getOptions().get(OPTION_EVENT_BUS_INDEX);
            if (index == null) {
                messager.printMessage(Diagnostic.Kind.ERROR, "No option " + OPTION_EVENT_BUS_INDEX +
                        " passed to annotation processor");
                return false;
            }
            verbose = Boolean.parseBoolean(processingEnv.getOptions().get(OPTION_VERBOSE));
            int lastPeriod = index.lastIndexOf('.');
            //package名字
            String indexPackage = lastPeriod != -1 ? index.substring(0, lastPeriod) : null;

            //region 检查annotations.isEmpty env.processingOver
            round++;
            if (verbose) {
                //处理round第几个回合,annotations不空,处理状态
                messager.printMessage(Diagnostic.Kind.NOTE, "Processing round " + round + ", new annotations: " +
                        !annotations.isEmpty() + ", processingOver: " + env.processingOver());
            }
            if (env.processingOver()) {//处理完了
                if (!annotations.isEmpty()) {//annotations不空
                    //报错
                    messager.printMessage(Diagnostic.Kind.ERROR,
                            "Unexpected processing state: annotations still available after processing over");
                    return false;
                }
            }
            if (annotations.isEmpty()) {//如果annotations为空,返回
                return false;
            }
            //endregion

            if (writerRoundDone) {//如果处理完了,还进入这个流程,说明有问题
                messager.printMessage(Diagnostic.Kind.ERROR,
                        "Unexpected processing state: annotations still available after writing.");
            }
            // 取出所有订阅者信息
            collectSubscribers(annotations, env, messager);
            // 检查订阅者信息
            checkForSubscribersToSkip(messager, indexPackage);

            if (!methodsByClass.isEmpty()) {
                // 查找到的注解的方法不为空,生成Java文件
                createInfoIndexFile(index);
            } else {
                messager.printMessage(Diagnostic.Kind.WARNING, "No @Subscribe annotations found");
            }
            writerRoundDone = true;
        } catch (RuntimeException e) {
            // IntelliJ does not handle exceptions nicely, so log and print a message
            e.printStackTrace();
            messager.printMessage(Diagnostic.Kind.ERROR, "Unexpected error in EventBusAnnotationProcessor: " + e);
        }
        return true;
    }

    //region collectSubscribers ok
    private void collectSubscribers(Set annotations, RoundEnvironment env, Messager messager) {
        // 遍历所有注解
        for (TypeElement annotation : annotations) {//TypeElement RoundEnvironment
            // 拿到被注解标记的所有元素
            //RoundEnvironment的getElementsAnnotatedWith方法, 这个方法会返回被当前注解标记的所有元素,可能是类、变量、方法等。
            Set elements = env.getElementsAnnotatedWith(annotation);
            // 遍历所有元素
            for (Element element : elements) {//Element
                // 元素必须是方法,因为@Subscribe只能注解方法
                if (element instanceof ExecutableElement) {//ExecutableElement
                    ExecutableElement method = (ExecutableElement) element;
                    // 检查方法,条件:订阅方法必须是非静态的,公开的,参数只能有一个
                    if (checkHasNoErrors(method, messager)) {
                        // 取封装订阅方法的类
                        TypeElement classElement = (TypeElement) method.getEnclosingElement();
                        // 以类名为key,保存订阅方法
                        //在方法最后,将筛选出来的订阅者和方法都保存在了methodsByClass这个容器里,这个容器的数据结构是>>,可以存储订阅类中的多个方法。
                        methodsByClass.putElement(classElement, method);
                    }
                } else {
                    messager.printMessage(Diagnostic.Kind.ERROR, "@Subscribe is only valid for methods", element);
                }
            }
        }
    }
    //endregion

    //region checkForSubscribersToSkip ok
    
    
    private void checkForSubscribersToSkip(Messager messager, String myPackage) {
        // 遍历所有订阅类
        for (TypeElement skipCandidate : methodsByClass.keySet()) {
            TypeElement subscriberClass = skipCandidate;
            //开启子类到父类的while循环检查
            while (subscriberClass != null) {
                // 订阅类必须是可访问的,否则记录并直接break,检查下一个订阅类
                if (!isVisible(myPackage, subscriberClass)) {
                    boolean added = classesToSkip.add(skipCandidate);
                    if (added) {
                        String msg;
                        if (subscriberClass.equals(skipCandidate)) {
                            msg = "Falling back to reflection because class is not public";
                        } else {
                            msg = "Falling back to reflection because " + skipCandidate +
                                    " has a non-public super class";
                        }
                        messager.printMessage(Diagnostic.Kind.NOTE, msg, subscriberClass);
                    }
                    break;
                }
                // 拿到订阅类的所有订阅方法
                List methods = methodsByClass.get(subscriberClass);
                if (methods != null) {
                    // 检查所有订阅方法
                    for (ExecutableElement method : methods) {//ExecutableElement
                        String skipReason = null;
                        // 拿到订阅方法的参数,开始对参数进行检查
                        VariableElement param = method.getParameters().get(0);//VariableElement
                        // 取得参数(Event)的类型
                        //返回此元素定义的类型。返回值用TypeMirror表示,TypeMirror表示了Java编程语言中的类型,包括基本类型,一般用来做类型判断。
                        TypeMirror typeMirror = getParamTypeMirror(param, messager);
                        // 参数(Event)的类型必须是类或接口
                        if (!(typeMirror instanceof DeclaredType) ||
                                !(((DeclaredType) typeMirror).asElement() instanceof TypeElement)) {
                            skipReason = "event type cannot be processed";
                        }
                        if (skipReason == null) {
                            // 拿到参数(Event)元素
                            TypeElement eventTypeElement = (TypeElement) ((DeclaredType) typeMirror).asElement();
                            // 检查参数(Event)元素是不是可访问的
                            if (!isVisible(myPackage, eventTypeElement)) {
                                skipReason = "event type is not public";
                            }
                        }
                        if (skipReason != null) {
                            // 将不合格的订阅类记录下来
                            boolean added = classesToSkip.add(skipCandidate);
                            if (added) {
                                String msg = "Falling back to reflection because " + skipReason;
                                if (!subscriberClass.equals(skipCandidate)) {
                                    msg += " (found in super class for " + skipCandidate + ")";
                                }
                                messager.printMessage(Diagnostic.Kind.NOTE, msg, param);
                            }
                            break;
                        }
                    }
                }
                // 切换到父类,若父类是系统的类,则返回null,结束while循环
                subscriberClass = getSuperclass(subscriberClass);
            }
        }
    }

    private TypeMirror getParamTypeMirror(VariableElement param, Messager messager) {
        // 获取元素类型
        TypeMirror typeMirror = param.asType();
        // Check for generic type 检查泛型类型
        // 元素类型必须得是类或接口类型
        //你可以把DeclaredType (type)看作是一个类的泛型类型(例如List );
        // 与基本上忽略泛型类型的TypeElement (element)相比(例如List )。
        if (typeMirror instanceof TypeVariable) {//TypeVariable
            // 获取该类型变量的上边界,如果有extends,则返回父类,否则返回Object
            TypeMirror upperBound = ((TypeVariable) typeMirror).getUpperBound();
            // 是声明类型
            if (upperBound instanceof DeclaredType) {//DeclaredType
                if (messager != null) {
                    messager.printMessage(Diagnostic.Kind.NOTE, "Using upper bound type " + upperBound +
                            " for generic parameter", param);
                }
                // 替换参数类型为上边界的类型
                typeMirror = upperBound;
            }
        }
        return typeMirror;
    }
    //endregion

    //region createInfoIndexFile ok

    
    private void createInfoIndexFile(String index) {
        BufferedWriter writer = null;
        try {
            // 通过编译环境的文件工具创建Java文件
            JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(index);

            // 截取出包名
            int period = index.lastIndexOf('.');
            String myPackage = period > 0 ? index.substring(0, period) : null;
            // 截取出类名
            String clazz = index.substring(period + 1);
            //开始向Java文件中写入代码
            writer = new BufferedWriter(sourceFile.openWriter());
            if (myPackage != null) {
                writer.write("package " + myPackage + ";nn");
            }
            writer.write("import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;n");
            writer.write("import org.greenrobot.eventbus.meta.SubscriberMethodInfo;n");
            writer.write("import org.greenrobot.eventbus.meta.SubscriberInfo;n");
            writer.write("import org.greenrobot.eventbus.meta.SubscriberInfoIndex;nn");
            writer.write("import org.greenrobot.eventbus.ThreadMode;nn");
            writer.write("import java.util.HashMap;n");
            writer.write("import java.util.Map;nn");
            writer.write("n");
            writer.write("public class " + clazz + " implements SubscriberInfoIndex {n");
            writer.write("    private static final Map, SubscriberInfo> SUBSCRIBER_INDEX;nn");
            writer.write("    static {n");
            writer.write("        SUBSCRIBER_INDEX = new HashMap, SubscriberInfo>();nn");
            // 写入查找到的订阅者的相关代码
            writeIndexLines(writer, myPackage);
            writer.write("    }nn");
            writer.write("    private static void putIndex(SubscriberInfo info) {n");
            writer.write("        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);n");
            writer.write("    }nn");
            writer.write("    @Overriden");
            writer.write("    public SubscriberInfo getSubscriberInfo(Class subscriberClass) {n");
            writer.write("        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);n");
            writer.write("        if (info != null) {n");
            writer.write("            return info;n");
            writer.write("        } else {n");
            writer.write("            return null;n");
            writer.write("        }n");
            writer.write("    }n");
            writer.write("}n");
        } catch (IOException e) {
            throw new RuntimeException("Could not write source for " + index, e);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    //Silent
                }
            }
        }
    }

    private void writeIndexLines(BufferedWriter writer, String myPackage) throws IOException {
        // 遍历methodsByClass
        for (TypeElement subscriberTypeElement : methodsByClass.keySet()) {//TypeElement
            // 跳过不合格的订阅者
            if (classesToSkip.contains(subscriberTypeElement)) {
                continue;
            }
            // 获取订阅类的字符串名称,格式是:包名.类名.class
            String subscriberClass = getClassString(subscriberTypeElement, myPackage);
            // 再一次检查是否可访问
            if (isVisible(myPackage, subscriberTypeElement)) {
                writeLine(writer, 2,
                        "putIndex(new SimpleSubscriberInfo(" + subscriberClass + ".class,",
                        "true,", "new SubscriberMethodInfo[] {");
                // 取出订阅类的所有订阅方法
                List methods = methodsByClass.get(subscriberTypeElement);//ExecutableElement
                // 生成 [new 一个SubscriberMethodInfo,并将订阅方法的相关信息写入]ava的代码
                writeCreateSubscriberMethods(writer, methods, "new SubscriberMethodInfo", myPackage);
                writer.write("        }));nn");
            } else {
                writer.write("        // Subscriber not visible to index: " + subscriberClass + "n");
            }
        }
    }

    //很简单,遍历查找到的所有订阅者,然后跳过不合法的订阅者,生成写入订阅者的代码。
    //显然,writeCreateSubscriberMethods方法中生成了写入订阅方法的代码:
    private void writeCreateSubscriberMethods(BufferedWriter writer, List methods,
                                              String callPrefix, String myPackage) throws IOException {
        // 遍历订阅类中的所有订阅方法
        for (ExecutableElement method : methods) {//ExecutableElement
            // 获取方法参数
            List parameters = method.getParameters();//VariableElement
            // 取出第一个参数的参数镜像Mirror
            TypeMirror paramType = getParamTypeMirror(parameters.get(0), null);//TypeMirror
            // 通过参数类型拿到参数元素
            TypeElement paramElement = (TypeElement) processingEnv.getTypeUtils().asElement(paramType);//TypeElement
            // 方法名
            String methodName = method.getSimpleName().toString();
            // 参数类型 类名
            String eventClass = getClassString(paramElement, myPackage) + ".class";

            // 获取方法上的注解
            Subscribe subscribe = method.getAnnotation(Subscribe.class);
            List parts = new ArrayList<>();
            parts.add(callPrefix + "("" + methodName + "",");
            String lineEnd = "),";
            // 获取注解的值
            if (subscribe.priority() == 0 && !subscribe.sticky()) {
                if (subscribe.threadMode() == ThreadMode.POSTING) {
                    parts.add(eventClass + lineEnd);
                } else {
                    parts.add(eventClass + ",");
                    parts.add("ThreadMode." + subscribe.threadMode().name() + lineEnd);
                }
            } else {
                parts.add(eventClass + ",");
                parts.add("ThreadMode." + subscribe.threadMode().name() + ",");
                parts.add(subscribe.priority() + ",");
                parts.add(subscribe.sticky() + lineEnd);
            }
            // 生成代码
            writeLine(writer, 3, parts.toArray(new String[parts.size()]));

            if (verbose) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Indexed @Subscribe at " +
                        method.getEnclosingElement().getSimpleName() + "." + methodName +
                        "(" + paramElement.getSimpleName() + ")");
            }
        }
    }
    //endregion

    //region ok
    private boolean checkHasNoErrors(ExecutableElement element, Messager messager) {//ExecutableElement
        if (element.getModifiers().contains(Modifier.STATIC)) {//Modifier
            messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must not be static", element);
            return false;
        }

        if (!element.getModifiers().contains(Modifier.PUBLIC)) {
            messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must be public", element);
            return false;
        }

        List parameters = ((ExecutableElement) element).getParameters();//VariableElement
        if (parameters.size() != 1) {
            messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must have exactly 1 parameter", element);
            return false;
        }
        return true;
    }

    
    private boolean isVisible(String myPackage, TypeElement typeElement) {//TypeElement
        // 获取修饰符
        Set modifiers = typeElement.getModifiers();
        boolean visible;
        if (modifiers.contains(Modifier.PUBLIC)) {//Modifier
            // public的直接return true
            visible = true;
        } else if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.PROTECTED)) {
            // private和protected的直接return false
            visible = false;
        } else {
            // 获取元素所在包名
            String subscriberPackage = getPackageElement(typeElement).getQualifiedName().toString();
            if (myPackage == null) {
                // 是否都在最外层,没有包名
                visible = subscriberPackage.length() == 0;
            } else {
                // 是否在同一包下
                visible = myPackage.equals(subscriberPackage);
            }
        }
        return visible;
    }

    //得到TypeElement父类的TypeElement
    private TypeElement getSuperclass(TypeElement type) {//TypeElement
        if (type.getSuperclass().getKind() == TypeKind.DECLARED) {//DECLARED宣布
            TypeElement superclass = (TypeElement) processingEnv.getTypeUtils().asElement(type.getSuperclass());//TypeElement
            String name = superclass.getQualifiedName().toString();
            if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
                // Skip system classes, this just degrades performance
                return null;
            } else {
                return superclass;
            }
        } else {
            return null;
        }
    }

    private String getClassString(TypeElement typeElement, String myPackage) {//TypeElement
        PackageElement packageElement = getPackageElement(typeElement);//PackageElement
        String packageString = packageElement.getQualifiedName().toString();
        String className = typeElement.getQualifiedName().toString();
        if (packageString != null && !packageString.isEmpty()) {
            if (packageString.equals(myPackage)) {
                className = cutPackage(myPackage, className);
            } else if (packageString.equals("java.lang")) {//todo java.lang下有基本数据类型的封装类
                className = typeElement.getSimpleName().toString();
            }
        }
        return className;
    }

    private void writeLine(BufferedWriter writer, int indentLevel, String... parts) throws IOException {
        writeLine(writer, indentLevel, 2, parts);
    }

    private void writeLine(BufferedWriter writer, int indentLevel, int indentLevelIncrease, String... parts)
            throws IOException {
        writeIndent(writer, indentLevel);
        int len = indentLevel * 4;
        //依次写入parts数组里的元素
        for (int i = 0; i < parts.length; i++) {
            String part = parts[i];
            if (i != 0) {
                if (len + part.length() > 118) {//一行如果超过118个字符先换行
                    writer.write("n");
                    if (indentLevel < 12) {
                        indentLevel += indentLevelIncrease;
                    }
                    writeIndent(writer, indentLevel);
                    len = indentLevel * 4;
                } else {
                    writer.write(" ");
                }
            }
            writer.write(part);//是这里
            len += part.length();
        }
        writer.write("n");
    }

    
    private PackageElement getPackageElement(TypeElement subscriberClass) {//TypeElement PackageElement
        Element candidate = subscriberClass.getEnclosingElement();//把…围起来; 围住;
        while (!(candidate instanceof PackageElement)) {//往上找
            candidate = candidate.getEnclosingElement();
        }
        return (PackageElement) candidate;
    }

    
    private String cutPackage(String paket, String className) {
        if (className.startsWith(paket + '.')) {
            // Don't use TypeElement.getSimpleName, it doesn't work for us with inner classes
            return className.substring(paket.length() + 1);
        } else {
            // Paranoia
            throw new IllegalStateException("Mismatching " + paket + " vs. " + className);
        }
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        //javax.lang.model.SourceVersion RELEASE_8
        return SourceVersion.latest();
    }

    //缩进indent
    private void writeIndent(BufferedWriter writer, int indentLevel) throws IOException {
        for (int i = 0; i < indentLevel; i++) {
            writer.write("    ");
        }
    }
    //endregion
}

在java中理解'TypeElement'和'DeclaredType'接口

这些元素是用来组成软件的部分,也就是说,正如名称所暗示的那样, ExecutableElement包含可执行代码,描述一种存储的VariableElement和将它们组合在一起的TypeElement 。 它是Java编程语言(作为面向对象的语言)的一个特殊属性,没有顶级函数,也没有没有TypeElement全局变量,在这些变量中定义了它们。

换句话说,如果您编写一个Java程序,您将始终至少有一个.java源文件包含至少一个类型声明。 该TypeElement可能包含至少一个ExecutableElement来组成一个有用的软件。 TypeElement可能包含多个ExecutableElement , VariableElement和嵌套的TypeElement 。 这是你程序的结构。

你可以把DeclaredType (type)看作是一个类的泛型类型(例如List ); 与基本上忽略泛型类型的TypeElement (element)相比(例如List )。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/338130.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号