java中的apt的工作过程(代码片段)

fortitude fortitude     2022-12-14     517

关键词:

Java中的APT的工作过程

APT即Annotatino Processing Tool, 他的作用是处理代码中的注解, 用来生成代码, 换句话说, 这是用代码生成代码的工具, 减少boilerplate代码.

我们通过一个简单的例子来简单APT的工作过程, 因为本文demo不设计ide及gradle等, 请注意包名及import问题.

根据上一篇博客Java中的自定义注解, 首先设计一个自定义注解MyAnnotation.

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.SOURCE) // 只保留到编译阶段
@Target(ElementType.TYPE) // 可用于类, 接口..
public @interface MyAnnotation 

下面来看一下我们的主角, Processor:

package com.example;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import java.util.HashSet;
import java.util.Set;

public class MyProcessor extends AbstractProcessor 

    // Processor初始化回调
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) 
        super.init(processingEnv);
        System.out.println("MyProcessor init"); 
    

    // processor处理过程的回调, 如果需要生成代码, 就在这个方法中写. 这个demo暂时不演示代码生成.
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) 
        System.out.println("process");
        return false;
    

    @Override
    public Set<String> getSupportedAnnotationTypes() 
        // 在此处声明该processor支持的注解类型
        Set<String> set = new HashSet<>();
        set.add(MyAnnotation.class.getCanonicalName());
        return set;
    

    @Override
    public SourceVersion getSupportedSourceVersion() 
        return SourceVersion.latestSupported();
    

那么我们如何把这个apt注册给javac呢? 我们将项目以常规的模式打包, 但是在META-INF目录中加入一个services文件夹, 在其中创建一个名为javax.annotation.processing.Processor的文件, 以文本将processor的完整名字写进去, 如果有多个processor, 换行即可.

javax.annotation.processing.Processor的内容:

com.example.MyProcessor

最终jar包的结构:

mp.jar // jar包名字随意起
    com
        example
            MyProcess.class
            MyAnnotation.class
    META-INF
        services
            javax.annotation.processing.Processor
        MANIFEST.MF

测试

测试的例子很简单:

@MyAnnotation
public class Sample 
    public static void main(String[] args) 
        System.out.printf("Hello, World!");
    

我们用javac编译这个文件

$ javac -cp mp.jar Sample.java
MyProcessor init
process
process

可以看到, 我们的Process已经生成了, 但是process过程输出了两次, 原因可以参考下图:

技术图片

process的过程会进行两边, 我们代码生成的过程应该在第一遍, 因为第二次processor的过程应当负责做一些清理的工作, 某些打包工具可能不会编译在第二阶段生成的.java源文件.

if (!roundEnv.processingOver())  ... 

java解析javac源码apt执行原理(代码片段)

...c;大家的技术都在提升,如果自己还是原地踏步,工作10年还是在用着刚工作1-2年的技术在应对现在的开发,所以很多同学的感受是࿱ 查看详情

线程小酌之java中的阻塞队列(代码片段)

      最近在学习java中自带的JDK并发包,java.util.concurrent,发现功能很强大,其中之一就是工作中多次用到的线程工具类BlockingQueue。在实际开发工作和面试过程中,经常会考察对于该工具类的使用和理解。1.什... 查看详情

使用apt-get清理(代码片段)

...序已经卸载。apt-getcleanapt-getclean命令清除遗留在/var/cache中的已取回的包文件的本地仓库。它清除的目录是/var/cache/apt/archives/和/var/cache/apt/archives/partial/。它留在/var/cache/apt/archives中的唯一文件是lock文件和partial子目录。在运行清... 查看详情

android编译时注解处理apt(代码片段)

一、注解在使用Java语言开发的过程中,我们会经常看到各种各样的注解,@Override(表示方法的重写),@Deprecated(标记过时的元素方法,类或属性),@LayoutRes(表示的是布局资源),@IdRes(表示的是ID资源),@Drawa... 查看详情

android编译时注解处理apt(代码片段)

一、注解在使用Java语言开发的过程中,我们会经常看到各种各样的注解,@Override(表示方法的重写),@Deprecated(标记过时的元素方法,类或属性),@LayoutRes(表示的是布局资源),@IdRes(表示的是ID资源),@Drawa... 查看详情

java实现文件导出过程中的提示功能(代码片段)

文章目录目的实现(方案一)原理JavaEE中的Cookie操作创建Cookie修改Cookie销毁Cookie发送CookieJS中的Cookie操作document.cookie示例实现(方案二)原理XMLHttpRequest.send()XMLHttpRequest.onreadystatechangeXMLHttpRequest.re 查看详情

java实现文件导出过程中的提示功能(代码片段)

文章目录目的实现(方案一)原理JavaEE中的Cookie操作创建Cookie修改Cookie销毁Cookie发送CookieJS中的Cookie操作document.cookie示例实现(方案二)原理XMLHttpRequest.send()XMLHttpRequest.onreadystatechangeXMLHttpRequest.re 查看详情

aps高级排产减少生产过程中的瓶颈(代码片段)

瓶颈一般是指在整体中的关键限制因素。瓶颈在不同的领域有不同的含义。生产中的瓶颈是指那些限制工作流整体水平(包括工作流完成时间,工作流的质量等)的单个因素或少数几个因素。通常把一个流程中生产节... 查看详情

asm(代码片段)

...SM3.0,开始之前先思考几个问题:1.ASM是什么?2.ASM跟传说中的AOP三剑客APT、aspectJ、Javassit有什么关系?3.ASM是怎样修改class文件的?带着问题开始今天的分享:1.ASM是什么?ASM是一个Java字节码操控框架。它能被用来动态生成类或... 查看详情

mysql高级(代码片段)

...数的概念存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合2.存储过程和函数的好处存储过程和函数可以重复使用,减轻开发人员的工作量。类似于java中方法可以多次调用减少网络流量,存储过程和函数位于... 查看详情

shubuntu中的apt(高级软件包工具)命令(代码片段)

查看详情

java中的方法调用分析!详细解析静态分派和动态分派的执行过程(代码片段)

...内部的具体运行过程Class文件的编译过程不包括传统编译中的连接步骤Class文件中的一切方法调用在Class文件里面存储的都是符号引用,而不是方法在在实际运行时内存布局中的入口地址,即之前的直接引用:这样使得Java具有更强大... 查看详情

格式化每个工作表中的单元格(代码片段)

...在我的工作簿的所有工作表中做同样的事情(所有工作表中的相同单元格)。大概有40张,所以我需要用VBA编写这个任务。我记录了该过程,但不知道如何在所有工作表中编写代码来执行此操作。我记录的代码:SubMacro_1()''Macro_1M... 查看详情

一文读懂java中的代理模式(代码片段)

代理(Proxy)模式是我们在工作中广泛使用的设计模式之一,提供了对目标对象额外的访问方式。通过代理对象来访问目标对象,可以对目标对象进行功能的增强,即扩展目标对象的功能。例如在Spring中,AOP就是使用动态代理来... 查看详情

apt你真的了解吗?解析javac源码apt执行原理(代码片段)

...c;大家的技术都在提升,如果自己还是原地踏步,工作10年还是在用着刚工作1-2年的技术在应对现在的开发,所以很多同学的感受是:面试一年比一年“难”。在和一些同学的交流中,感觉很多同学的技术并不... 查看详情

银河麒麟v4.0.2安装gscloud的简单过程(代码片段)

1.本来想用tar包安装redis结果总是报错,提示需要maketest但是我已经maketest了所以还是使用apt-get来安装。2.方式apt-getupdate#不升级没法安装。apt-getinstallredis#安装完自动开起来一个服务。。很奇怪3.配置文件安装完之后配置文件就自... 查看详情

effectivejava在工作中的应用总结(代码片段)

简介: 《EffectiveJava》是一本经典的Java学习宝典,值得每位Java开发者阅读。笔者将书中和平日工作较密切的知识点做了部分总结。作者|宜秋来源|阿里技术公众号《EffectiveJava》是一本经典的Java学习宝典,值得每位Jav... 查看详情

linux软件安装之apt+dpkg工具(代码片段)

...源代码格式的软件包,因此简化了Unix系统上管理软件的过程。APT最早被设计成dpkg的前端,用来处理deb格式的 查看详情