手把手实现一个lombok

news2024/11/13 11:07:03

手把手实现一个lombok

    • 一、lombok原理 JSR269
    • 二、实现步骤
      • 1.工程与环境依赖
        • 注意细节
      • 2.注解处理器
      • 3.注解
      • 4.jcTree 修改语法
      • 4.新建模块依赖我们这个jar包进行编译
      • 5.源码调试

一、lombok原理 JSR269

什么是JSR ?

JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。

有超过300的JSR。一些更为明显的JSRs包括:

的JSR#规格或技术
1实时规范为Java(RTSJ规范)1.0
3Java管理扩展(JMX)的1.0,1.1和1.2 [ 2 ]
5Java API的XML处理(JAXP)1.0
8OSGI的开放服务网关规范
9次郎(联邦管理体系规范)1.0
12Java数据对象(JDO的)1.0
13改进的BigDecimal(Java平台,标准版#java.math)
14加入到Java编程语言(如J2SE 5.0的泛型类型)
16Java EE连接器架构(JCA)的1.0
19企业JavaBeans(EJB)2.0
22JAIN SLEE API规范(JSLEE)的1.0
30连接有限设备配置(CLDC)1.0 的Java ME
31用于XML绑定的Java体系结构(JAXB)的1.0
32JAIN SIP API规范(JSIP)的1.0,1.1和1.2的Java ME
36连接设备配置(CDC)的1.0为Java ME
37移动信息设备描述(MIDP)1.0为Java ME
40Java元数据接口(JMI)1.0
41一个简单的断言基金(J2SE 1.4中)
47日志 API规范(J2SE 1.4中)
48WBEM服务规范(J2SE 1.4中)
51新的I / O API的Java平台(J2SE 1.4的)(妞妞)
52JavaServer Pages标准标记库(JSTL)的1.0和1.1 [ 3 ]
53的Java Servlet 2.3和JavaServer页面(JSP)的1.2规格
54Java数据库连接(JDBC)3.0
56Java网络启动协议和API(JNLP的),1.0,1.5和6.0 [ 4 ](Java Web Start的)
58Java 2平台企业版(J2EE)的1.3
59Java 2平台标准版(J2SE)的1.4(梅林)
63用于XML处理的Java API(JAXP)1.1和1.2 [ 5 ]
68Java平台Micro版(Java ME)的1.0
73Java数据挖掘 API(JDM)1.0
75J2ME平台的PDA可选包
80的Java 的USB API
82蓝牙的Java API
88Java EE的应用程序部署
93用于XML注册的Java API(JAXR)1.0
94Java规则引擎API
102Java的文档对象模型(JDOM的)1.0
110Java API的WSDL(WSDL4J)1.0
112Java EE连接器架构(JCA)的1.5
113的Java Speech API的2(JSAPI2)
114Java数据库连接(JDBC)的RowSet实现
116的SIP Servlet API 1.0
118移动信息设备描述(MIDP)2.0为Java ME
120无线消息API(WMA)的
121应用程序隔离API
127的JavaServer Faces(JSF)的1.0和1.1 [ 6 ]
133Java内存模型和主题规范修订
135Java ME的Java移动媒体API(MMAPI)的
139有限连接设备配置(CLDC)1.1为Java ME
140服务定位协议 “(SLP)的Java API
141会话描述协议(SDP)的API为Java
151Java 2平台企业版(J2EE)的1.4
152JavaServer页面(JSP)的2.0
153企业JavaBeans(EJB)2.1
154的Java Servlet 2.4和2.5规格[ 7 ]
160Java管理扩展(JMX)的远程API 1.0
166并发实用程序(J2SE 5.0中的java.util.concurrentjava.util.concurrent.atomicjava.util.concurrent.locks
168Portlet规范 1.0
170内容库的Java API(JCR)的1.0
172Java ME的Web服务规范
173使用StAX(XML的流式API)
175一个Java编程语言的元数据工具
176Java 2平台标准版(J2SE)的5.0(虎)
177J2ME(SATSA的安全和信任服务API)
179位置API为Java ME 1.0
180会话发起协议(SIP)API为Java ME
181用于Java平台的Web服务元数据
184移动3D图形API为Java ME 1.0和1.1
185无线行业Java技术(JTWI的)
187即时消息(的Java ME和Java SE中)
198一个标准扩展API 的集成开发环境
199Java编译器 API
201扩展Java编程语言的枚举,自动装箱,静态导入循环和增强(J2SE 5.0的)
202Java类文件规范更新
203更多新的I / O API的Java平台(NIO2)
204Unicode增补字符支持(增加了J2SE 5.0的支持Unicode的 3.1)
205无线消息API 2.0 “(WMA)2.0
206用于XML处理的Java API(JAXP)1.3
208Java业务集成(JBI)的1.0
215Java社区进程(JCP)2.6
218连接设备配置(CDC)的1.1为Java ME
220企业JavaBeans(EJB)3.0
221Java数据库连接(JDBC)4.0
222用于XML绑定(JAXB)的2.0 Java体系结构
223Java SE 6中Java平台的脚本
224XML Web服务的Java API(JAX-WS的),继承的JAX-RPC
225的XQuery API为Java(XQJ的)
226可调节2D矢量图形 API 的Java ME
229支付API(PAPI的)
231针对OpenGL的Java绑定
234高级多媒体补充 API为Java ME
235服务数据对象(SDO),
239OpenGL ES的Java绑定
240JAIN SLEE API规范(JSLEE)的1.1
241Groovy编程语言
243Java数据对象(JDO的)2.0
244的Java平台企业版(Java EE)的5
880JavaServer页面(JSP)的2.1
247Java数据挖掘 API(JDM)2.0
248移动服务架构
249移动服务架构2
250常见的注解的Java平台(Java元数据设施)
252的JavaServer Faces(JSF)的1.2
253移动电话服务API(MTA),
255Java管理扩展(JMX)2.0
256移动传感器API
257非接触式通信API(NFC技术)
260Javadoc的标签技术更新
269可插拔注解处理API(Java元数据设施)
270Java平台标准版(Java SE)的6(野马)
271移动信息设备描述(MIDP)3.0为Java ME
274BeanShell的脚本语言
275单位规范(见计量单位)
276设计时元数据的的JavaServer面临的组件
277Java模块系统
280对于Java ME的XML API
281IMS的服务API(见的IMS)
282为Java实时规范(RTSJ规范)1.1
283内容库的Java API(JCR)的2.0
286Portlet规范 2.0
289的SIP Servlet API 1.1
290Java语言与XML用户界面标记集成(XML用户界面)
291针对Java SE动态组件的支持(见的OSGi)
292JavaTM平台上支持动态类型语言
293位置API为Java ME 2.0
294在Java编程语言的改进模块化支持
296Swing应用程序框架(Java SE 7中)
299Java的上下文和依赖注入(焊接)
301JSF Portlet的桥梁
303Bean验证
307移动网络和移动数据API(截至7月正式计划,20日,2007年,但官方发布2。问:2008
308注解的Java类型(Java SE的8)
311RESTful Web服务的Java API(JAX-RS的)1.0和1.1
314的JavaServer Faces(JSF)的2.0
316的Java平台企业版(Java EE)的6
317Java持久性API(JPA)的2.0
322Java EE连接器架构(JCA)的1.6
325IMS通信促成(ICE)的(见的IMS)
330对Java的依赖注入
343Java消息服务 2.0(JMS)
354Java的货币及货币的API
901Java语言规范,第三版(JLS的)(J2SE 5.0的集成的JSR 14,41,133,175,201和204)
907Java事务API(JTA),1.0和1.1
912Java 3D的 API 1.3
913Java社区进程(JCP)的2.0,2.1和2.5。[ 8 ]
914Java消息服务(JMS)API的1.0和1.1
924第二版(JVM)Java虚拟机规范(J2SE 5.0的)。[ 9 ]
926的Java 3D API 1.5

JSR269 可插拔的注解处理API,其原理如下:

在这里插入图片描述

二、实现步骤

1.工程与环境依赖

  1. 配置maven 插件,pom.xml 编译参数
<build>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <encoding>UTF-8</encoding>
                    <compilerArgs>
                        <arg>-parameters</arg>
                        <arg>-proc:none</arg>
                        <arg>-XDignore.symbol.file</arg>
                    </compilerArgs>
                    <compilerArguments>
                        <bootclasspath>
                            ${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar${path.separator}${java.home}/../lib/tools.jar
                        </bootclasspath>
                    </compilerArguments>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

注意细节

  1. Lombok项目本身要加 编译 参数 ,防止编译处理器无法实例化:-proc:none
  2. 要添加编译 类路径 bootclasspath: 指定tool.jar
  3. 在测试的时候 要构建一个新的工程,用一个新的IDEA窗口打开

2.注解处理器

  • 打印编译信息
  1. 编写注解处理器,实现AbstractProcessor
  2. 基于SPI指定处理器的路径 :工程/resources/META-INF/services/javax.annotation.processing.Processor
  3. 打印消息的时候,maven 用System.out, idea用Messager
  4. 我当时用ide 编译时一直报错 ,我没太在意使用mvn 命令处理的, mvn命令没错误

Error:java: 服务配置文件不正确, 或构造处理程序对象javax.annotation.processing.Processor: Provider com.wfg.HelloProcessor not found时抛出异常错误

在项目编写的目录下操作下面的命令

mvn compile  编译
mvn package 打包
mvn install 安装到本地仓库

mvn exec:java -Dexec.mainClass="hello.HelloWorld" 运行main类,此处用不到这个命令
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("com.wfg.MyHello")
public class HelloProcessor  extends AbstractProcessor {
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        System.out.println("这是我的第一人编译注释处理器");
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,"这是我的处理器");
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return false;
    }
}

3.注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface MyHello {

}

4.jcTree 修改语法

  • 构建一个hello world 语句

import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Names;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.Set;


@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("org.myLombok.Hello")
public class HelloProcessor  extends AbstractProcessor {
    private JavacTrees javacTrees; // 获取 JcTree
    private TreeMaker treeMaker; // 构建生成 jcTree
    private Names names;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        System.out.println("这是我的第一人编译注释处理器");
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,"这是我的处理器");
        javacTrees = JavacTrees.instance(processingEnv);// 语法树
        Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
        this.treeMaker = TreeMaker.instance(context);
        super.init(processingEnv);
        this.names = Names.instance(context);

    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        annotations.stream()
                .flatMap(t->roundEnv.getElementsAnnotatedWith(t).stream())
                .forEach(t->{
                    JCTree tree = javacTrees.getTree(t);
                 // 基于访问者设计模式 去修改方法
                    tree.accept(new TreeTranslator(){
                        @Override
                        public void visitMethodDef(JCTree.JCMethodDecl tree) {
//                            System.out.println("hello world");
                            JCTree.JCStatement sysout = treeMaker.Exec(
                                    treeMaker.Apply(
                                            List.nil(),
                                            select("System.out.println"),
                                            List.of(treeMaker.Literal("hello world!")) // 方法中的内容
                                    )
                            );
                            // 覆盖原有的语句块
                            tree.body.stats=tree.body.stats.append(sysout);
                            super.visitMethodDef(tree);
                        }
                    });
                });

        return true;
    }


    private JCTree.JCFieldAccess select(JCTree.JCExpression selected, String expressive) {
        return treeMaker.Select(selected, names.fromString(expressive));
    }

    private JCTree.JCFieldAccess select(String expressive) {
        String[] exps = expressive.split("\\.");
        JCTree.JCFieldAccess access = treeMaker.Select(ident(exps[0]), names.fromString(exps[1]));
        int index = 2;
        while (index < exps.length) {
            access = treeMaker.Select(access, names.fromString(exps[index++]));
        }
        return access;
    }

    private JCTree.JCIdent ident(String name) {
        return treeMaker.Ident(names.fromString(name));
    }
}

4.新建模块依赖我们这个jar包进行编译

/**
 * @author wufagang
 * @description
 * @date 2023年04月18日 20:46
 */
@MyHello
public class HelloDemo {
}

编译后到效果
在这里插入图片描述

5.源码调试

测试模块引入下面的插件

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 神经网络回归

神经网络回归数据&#xff0c;21条&#xff0c;每条12个月&#xff0c;根据输入预测下一年 数据集&#xff1a; 下载链接 620906209062090620906209062090620906209062090620906209062090660936365969622628916949069597656066534455211622826735957783727886869762952670916…

【远程访问及控制】

目录 一、OpenSSH服务器1.1、SSH远程管理1.2、ssh服务器的端口1.3、修改端口号1.4、设置用户登录 二、实验2.1、设置白名单2.2、设置黑名单 三、sshd 服务支持两种验证方式:3.1、密码验证3.2、密钥对验证公钥和私钥的关系&#xff1a; 四、使用SSH客户端程序4.1、ssh 远程登录4…

java项目之疫情网课管理系统(springboot+vue源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的疫情网课管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

Java集合框架(Collection)

集合框架 一个Java对象可以在内部持有若干其他Java对象&#xff0c;并对外提供访问接口&#xff0c;把这种Java对象称为集合 集合框架都包含三大块内容&#xff1a;&#xff08;接口、实现、算法&#xff09; &#xff08;1&#xff09;对外的接口 &#xff08;2&#xff09;…

【C++】string类的简单模拟实现

目录 string类初识 string模拟实现 string类成员变量 构造函数 拷贝构造 赋值运算符重载 析构函数 深浅拷贝问题 string类初识 由于C语言中的字符串不太符合OOP(面向对象编程)的思想&#xff0c;而且其底层空间需要用户自己管理&#xff0c;经常有访问越界的情况出现。…

模仿风宇博客登录蒙层弹窗(vuex+computed实现)

效果图 使用了动态组件做组件切换使用vue内置的transition组件实现过渡效果&#xff0c;蒙层 和 弹框 都使用了transition&#xff0c;并嵌套vuex computed计算属性&#xff0c;实现数据 和 方法共享&#xff0c;让其它组件也能够控制到登录弹框蒙层使用了固定定位未实现&…

读取注册表中的REG_QWORD和REG_BINARY(二进制)类型数据

读取注册表中的REG_QWORD和REG_BINARY二进制类型数据 发现的问题注册表中的一些概念&#xff08;统一认识&#xff09;读取代码&#xff08;字节数据大于8的会显示f开头的前缀&#xff09;说明&#xff08;备注&#xff09;改进代码参考链接 发现的问题 首先我们要明确&#x…

【Jetpack】DataBinding 架构组件 ⑥ ( RecyclerView 数据绑定 )

文章目录 一、RecyclerView 数据绑定核心要点1、启用数据绑定 / 导入依赖2、RecyclerView 条目 DataBinding 布局3、自定义 RecyclerView.Adapter 适配器要点 ( 本博客重点 ★ ) 二、RecyclerView 数据绑定源码示例1、build.gradle 构建脚本 ( 启用数据绑定 / 导入依赖 )2、主界…

ggplot中的注释图层annotate

文章目录 介绍利用注释层添加图形利用注释层添加文本利用注释层添加公式 介绍 ggplot作图包中除了常见的geom图层外&#xff0c;还有一个annotate的注释图层&#xff0c;实现对作图对象的额外添加&#xff0c;其添加要素不在ggplot()所接受的数据框中。 利用注释层添加图形 …

家政服务APP小程序开发功能详解

随着人们生活水平的提高&#xff0c;对家政服务的要求也越来越高。而传统的到家政公司寻找服务人员的方法显然已经无法满足人们需求&#xff0c;取而代之的是线上预约家政服务。家政服务App小程序软件可以满足用户在线预约&#xff0c;还可以根据自己的需求定制家政服务、选择家…

【Hadoop-CosDistcp】通过CosDistcp的方式迁移Cos中的数据至HDFS

【Hadoop-CosDistcp】通过CosDistcp的方式迁移Cos中的数据至HDFS 1&#xff09;功能说明2&#xff09;使用环境3&#xff09;下载与安装4&#xff09;原理说明5&#xff09;参数说明6&#xff09;使用示例7&#xff09;迁移 Cos 中的数据至 HDFS 及数据校验7.1.数据迁移7.2.数据…

【Unity入门】16.脚本引用组件

【Unity入门】脚本引用组件 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;脚本引用普通组件 &#xff08;1&#xff09;点击控制音频播放 还记得我们的车载音乐AudioSource吗&#xff1f;…

zabbix搭建

1.环境 本实验使用一台centos7主机&#xff0c;关闭了firewalld和selinux服务&#xff0c;zabbix版本为5.0版本&#xff0c;mysql使用版本为5.7版本 若要搭建6.0以上版本的zabbix&#xff0c;则需要使用mysql 8.0以上的版本 其它版本的zabbix可参考zabbix官网:Download and…

YOLOv5+单目实现三维跟踪(python)

YOLOv5单目跟踪&#xff08;python&#xff09; 1. 目标跟踪2. 测距模块2.1 设置测距模块2.2 添加测距 3. 主代码4. 实验效果 相关链接 1. YOLOv5单目测距&#xff08;python&#xff09; 2. YOLOv7单目测距&#xff08;python&#xff09; 3. YOLOv7单目跟踪&#xff08;pytho…

C++练级之初级:第四篇

C练级之初级&#xff1a;第四篇 引用 C练级之初级&#xff1a;第四篇1.引用1.1引用的介绍1.2引用的使用场景1.3常引用 2.引用的底层3.引用的与指针的比较 总结 1.引用 1.1引用的介绍 &#x1f914;首先还是一个问题&#xff0c;引用是解决C语言什么不足&#xff1f; 指针在&am…

Python自动化sql注入:布尔盲注

在sql注入时&#xff0c;使用python脚本可以大大提高注入效率&#xff0c;这里演示一下编写python脚本实现布尔盲注的基本流程&#xff1a; 演示靶场&#xff1a;sqli-labs 布尔盲注 特点&#xff1a;没有回显没有报错&#xff0c;但根据sql语句正常与否返回不同结果&#x…

新手做电商直播带货怎么和快递合作谈价格

新手做电商直播带货怎么和快递合作谈价格达人带货一般怎样的合作模式&#xff1f;#达人带货 #直播带货 #红人 #百收网 跟快递谈价其实是有方法的&#xff0c;快递的价格不是说不能打下来&#xff0c;就是需要你们多一点点的心机。这个视频我就再给你们补充三个方法&#xff0c;…

HCIP之STP

企业网三层架构 线路冗余—二层网络桥接环路 因为路由器的路由表是由相对完善的计算所得&#xff0c;且存在防环规则&#xff1b;故路由器物理链路上实施备份时&#xff0c;一般不会出现环路&#xff1b;但交换转发数据依赖MAC表&#xff08;CAM表&#xff09;&#xff0c;该表…

【模式识别4】YOLO目标检测数据集xml格式转txt格式

YOLO目标检测数据集xml格式转txt格式 1. 转换前的xml格式2. xml格式转txt格式代码2.1 源代码2.2 需要修改的地方 3. 转换后的txt格式 代码资源&#xff1a;voc2txt.py 1. 转换前的xml格式 如果我们使用LabelImg工具标注数据集&#xff0c;生成的xml文件如下&#xff1a; xml…

Linux运维:推荐八款Linux远程连接工具

目录 2、XShell 3、SecureCRT 4、PuTTY 5、WindTerm 6、iTerm2 7、MobaXterm 8、Termius 今天给大家推荐八款Linux远程连接工具&#xff0c;非常实用&#xff0c;希望对大家能有所帮助&#xff01; 1、NxShell NxShell是一款开源的Linux远程管理工具&#xff0c;是我日…