java中javac AbstractProcessor有什么用

技术java中javac AbstractProcessor有什么用小编给大家分享一下java中javac AbstractProcessor有什么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!它可以

边肖,让我们与你分享java中javac抽象处理器的使用。希望大家看完这篇文章后有所收获。我们一起讨论一下吧!

00-1010当然,它做的是生成新的类或者修改原来的类。例如,您可以在遇到这种情况时使用它:

反思是如此缓慢。我在一家大工厂见过大量的Gson。因为Gson在序列化中广泛使用反射,所以每个字段和每个get和set都需要反射,这会带来性能问题。解决方案是使用它来最小化反射(用JSONObject替换)

生成的代码可以在有注释的地方阅读,简而言之,有很多(一些android orm框架)

00-1010 javax . annotation . processing . processing处理器接口会提供注释处理,根据SPI协议进行扩展,jdk默认有很多处理器。

00-1010注释处理器是最重要的扩展处理类。

注意:请确保已经成功配置了JAVA的环境变量,并将tools.jar(来自这个包)添加到自己计算机的环境变量中。

ProcessingEnvironment是注释处理工具的集合。元素是表示程序元素的接口,程序元素可以是包、类、方法或变量。元素的已知子接口有:

java中javac  AbstractProcessor有什么用

PackageElement表示包程序元素。提供对有关包及其成员的信息的访问。

ExecutableElement表示类或接口的方法、构造函数或初始值设定项(静态或实例),包括注释类型元素。

TypeElement表示类或接口程序元素。提供对有关类型及其成员的信息的访问。请注意,枚举类型是一种类型,而注释类型是一种接口。

元素表示字段、枚举常量、方法或构造函数参数、局部变量或异常参数。00-1010关注过程方法

//来自javax . annotation . processing;

publicatabstractclass abstractprocessoriimplements processor {

//集合中指定的支持的注释类型的名称(这里必须是完整的包名类名)

public setstringsetsupportedannotationtypes(){ 0

supportedannocationtypessat=this . getclass()。getAnnotation(supportedannotationtypes . class);

if(sat==null){ 0

if(isInitialized())

processingEnv.getMessager()。打印消息(诊断。善良。警告,

(=NationalBureauofStandards)国家标准局

p;                             "No SupportedAnnotationTypes annotation " +
                                                             "found on " + this.getClass().getName() +
                                                             ", returning an empty set.");
                return Collections.emptySet();
            }
            else
                return arrayToSet(sat.value());
        }
    // 指定当前正在使用的Java版本
    public SourceVersion getSupportedSourceVersion() {
        SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
        SourceVersion sv = null;
        if (ssv == null) {
            sv = SourceVersion.RELEASE_6;
            if (isInitialized())
                processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
                                                         "No SupportedSourceVersion annotation " +
                                                         "found on " + this.getClass().getName() +
                                                         ", returning " + sv + ".");
        } else
            sv = ssv.value();
        return sv;
    }
    // 初始化处理器
    public synchronized void init(ProcessingEnvironment processingEnv) {
        if (initialized)
            throw new IllegalStateException("Cannot call init more than once.");
        Objects.requireNonNull(processingEnv, "Tool provided null ProcessingEnvironment");
 
        this.processingEnv = processingEnv;
        initialized = true;
    }
    /**
     * 这些注解是否由此 Processor 处理,该方法返回ture表示该注解已经被处理, 后续不会再有其他处理器处理; 返回false表示仍可被其他处理器处理
     */
    public abstract boolean process(Set<? extends TypeElement> annotations,
                                    RoundEnvironment roundEnv);
}

实现一个打印可以API的功能

由于本人是maven环境,以此展开讲

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <!--Disable annotation processing for ourselves-->
                <!--<compilerArgument>-proc:none</compilerArgument>-->
            </configuration>
        </plugin>
    </plugins>
</build>

步骤1:实现一个注解处理器

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface ApiAnnotation {
    String author() default "alex.chen";
    String date();
    int version() default 1;
}
@SupportedAnnotationTypes({"com.kxtx.annotation.ApiAnnotation"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
//@AutoService(Processor.class)
public class MyProcessor extends AbstractProcessor {
    //类名的前缀、后缀
    public static final String SUFFIX = "AutoGenerate";
    public static final String PREFIX = "My_";
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        Messager messager = processingEnv.getMessager();
        for (TypeElement typeElement : annotations) {
            for (Element e : env.getElementsAnnotatedWith(typeElement)) {
                //打印
                messager.printMessage(Diagnostic.Kind.WARNING, "Printing:" + e.toString());
                messager.printMessage(Diagnostic.Kind.WARNING, "Printing:" + e.getSimpleName());
                messager.printMessage(Diagnostic.Kind.WARNING, "Printing:" + e.getEnclosedElements().toString());
 
                //获取注解
                ApiAnnotation annotation = e.getAnnotation(ApiAnnotation.class);
                //获取元素名并将其首字母大写
                String name = e.getSimpleName().toString();
                char c = Character.toUpperCase(name.charAt(0));
                name = String.valueOf(c + name.substring(1));
                //包裹注解元素的元素, 也就是其父元素, 比如注解了成员变量或者成员函数, 其上层就是该类
                Element enclosingElement = e.getEnclosingElement();
                //获取父元素的全类名,用来生成报名
                String enclosingQualifiedname;
                if (enclosingElement instanceof PackageElement) {
                    enclosingQualifiedname = ((PackageElement) enclosingElement).getQualifiedName().toString();
                } else {
                    enclosingQualifiedname = ((TypeElement) enclosingElement).getQualifiedName().toString();
                }
                try {
                    //生成包名
                    String generatePackageName = enclosingQualifiedname.substring(0, enclosingQualifiedname.lastIndexOf("."));
                    // 生成的类名
                    String genarateClassName = PREFIX + enclosingElement.getSimpleName() + SUFFIX;
                    //创建Java 文件
                    JavaFileObject f = processingEnv.getFiler().createSourceFile(genarateClassName);
                    // 在控制台输出文件路径
                    messager.printMessage(Diagnostic.Kind.WARNING, "Printing: " + f.toUri());
                    Writer w = f.openWriter();
                    try {
                        PrintWriter pw = new PrintWriter(w);
                        pw.println("package " + generatePackageName + ";");
                        pw.println("\npublic class " + genarateClassName + " { ");
                        pw.println("\n    /** 打印值 */");
                        pw.println("    public static void print" + name + "() {");
                        pw.println("        // 注解的父元素: " + enclosingElement.toString());
                        pw.println("        System.out.println(\"代码生成的路径: " + f.toUri() + "\");");
                        pw.println("        System.out.println(\"注解的元素: " + e.toString() + "\");");
                        pw.println("        System.out.println(\"注解的版本: " + annotation.version() + "\");");
                        pw.println("        System.out.println(\"注解的作者: " + annotation.author() + "\");");
                        pw.println("        System.out.println(\"注解的日期: " + annotation.date() + "\");");
 
                        pw.println("    }");
                        pw.println("}");
                        pw.flush();
                    } finally {
                        w.close();
                    }
                } catch (IOException e1) {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                            e1.toString());
                }
            }
        }
        return true;
    }
}

步骤2:配置一个spi,在resources目录新建META-INF/services/javax.annotation.processing.Processor,内容为MyProcessor类全名。

步骤3:在另一个项目中使用@ApiAnnotation就会发现生成了一个新My_feignAutoGenerate.class文件:

public class My_feignAutoGenerate {
    public My_feignAutoGenerate() {
    }
    public static void printStartUp() {
        System.out.println("代码生成的路径: file:/C:/Users/Administrator/Desktop/feign-async-master/target/generated-sources/annotations/My_feignAutoGenerate.java");
        System.out.println("注解的元素: com.github.feign.StartUp");
        System.out.println("注解的版本: 1");
        System.out.println("注解的作者: alex");
        System.out.println("注解的日期: 2019-03-6");
    }
}

到这里基本上已经演示完了。

google的 auto-service

<dependency>
    <groupId>com.google.auto.service</groupId>
    <artifactId>auto-service</artifactId>
    <version>1.0-rc2</version>
</dependency>

这个类库非常有用,它非常简单,使用@AutoService(Processor.class)会基于该接口和注解的类上自动帮我们生成META-INF/services下对应spi文件。它实现的原理就是通过注解处理器。

javapoet

有没有觉得上面pw.println("package " + generatePackageName + ";");这样的代码很痛苦啊?

JavaPoet is a Java API for generating .java source files.

package com.example.helloworld; 
public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, JavaPoet!");
  }
}
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, JavaPoet!")
    .build();
 
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
    .addMethod(main)
    .build();
 
JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
    .build();
 
javaFile.writeTo(System.out);

你喜欢的lombok实现原理是怎样的呢?

lombok(用来帮助开发人员消除 Java 对象 的冗长),非常好用

java中javac AbstractProcessor有什么用

看完了这篇文章,相信你对“java中javac AbstractProcessor有什么用”有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/77263.html

(0)

相关推荐

  • liunx如何安装nodejs

    技术liunx如何安装nodejs本篇内容主要讲解“liunx如何安装nodejs”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“liunx如何安装nodejs”吧!

    攻略 2021年11月19日
  • 自己吊顶方法图解,塑料扣板吊顶怎么安装图解

    技术自己吊顶方法图解,塑料扣板吊顶怎么安装图解1、确定吊顶安装位置在安装之前,我们需要先明确它的安装位置以及安装高度,这样在安装时才不会手忙脚乱,才能提高安装效率自己吊顶方法图解。 当我们确定好安装高度后,需要用墨线在四

    生活 2021年10月27日
  • KEGG Network 数据库的原理是什么

    技术KEGG Network 数据库的原理是什么这期内容当中小编将会给大家带来有关KEGG Network 数据库的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。kegg o

    攻略 2021年12月2日
  • html中让图片靠右(html5怎么让文字在图片右边)

    技术html5如何实现图片往右这篇文章将为大家详细讲解有关html5如何实现图片往右,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 在html中,图片往右的

    攻略 2021年12月17日
  • Xamarin .机器人真机测试提示安装失败更新不兼容错误怎么办

    技术Xamarin.Android真机测试提示INSTALL_FAILED_UPDATE_INCOMPATIBLE错误怎么办小编给大家分享一下Xamarin.Android真机测试提示INSTALL_FAILED_UPD

    攻略 2021年12月21日
  • 混凝土试块强度评定,混凝土试块评定方法标准差怎么算

    技术混凝土试块强度评定,混凝土试块评定方法标准差怎么算评定水泥混凝土的抗压强度,应以标准养生28d 龄期的试件为准。试件为边长150mm 的立方体。试件3 件为1组。水泥混凝土抗压强度的合格标准混凝土试块强度评定:一、试

    生活 2021年10月25日