手把手实现一个lombok

这篇具有很好参考价值的文章主要介绍了手把手实现一个lombok。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、lombok原理 JSR269

什么是JSR ?

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

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

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

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

手把手实现一个lombok

二、实现步骤

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 {
}

编译后到效果
手把手实现一个lombok

5.源码调试

测试模块引入下面的插件文章来源地址https://www.toymoban.com/news/detail-422259.html

<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>

到了这里,关于手把手实现一个lombok的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手把手搭建一个压测脚本

    1. 背景         在业务开发完成,并且功能测试也正常,接下来就需要接口性能进行测试,也叫压力测试,即对接口进行极限施压,找到接口瓶颈。对于一般接口,需保证请求的耗时在 300ms 左右最后,但一些接口涉及的业务逻辑复杂,导致耗时严重,并且用户请求量也大

    2024年02月13日
    浏览(47)
  • 手把手带你搞懂AMS启动原理

    彻底搞懂AMS即ActivityManagerService,看这一篇就够了 最近那么多教学视频(特别是搞车载的)都在讲AMS,可能这也跟要快速启动一个app(甚至是提高安卓系统启动速度有关),毕竟作为安卓系统的核心系统服务之一,AMS以及PMS都是很重要的,而我之前在 应用的开端–PackageManag

    2024年02月12日
    浏览(38)
  • 手把手教你学AltiumDesigner之新建原理图库

    学好AD,请多加练习!!! 学好AD,请多加练习!!! 学好AD,请多加练习!!! 既然是手把手教学,那么就必须从零开始。电路的设计基础就是要有电子元器件,那么我们搭建原理图的第一步就是拥有我们需要的元器件。那就准备好做元器件的原理图吧。 因为本次我们要以

    2023年04月08日
    浏览(28)
  • 手把手自己制作一个飞书机器人

    飞书机器人 如果你想添加新的对话逻辑,你只需要在 ChatApi.py 中添加新的if条件判断语句即可。如果你能开发出新功能,请在仓库中提出Pull requests合并请求,我将感激不尽! 2023年9月1日更新 更新了对话机器人返回帮助界面功能,用户发送“帮助”,返回机器人使用说明 20

    2024年02月03日
    浏览(91)
  • 手把手教你搭建一个Minecraft 服务器

    这次,我们教大家如何搭建一个我的世界服务器 首先,我们来到这个网站 MCVersions.net - Minecraft Versions Download List MCVersions.net offers an archive of Minecraft Client and Server jars to download, for both current and old releases! https://mcversions.net/   在这里,我们点击对应的版本,从左到右依次是稳定版

    2024年02月09日
    浏览(37)
  • 手把手教你用MindSpore训练一个AI模型!

    首先我们要先了解深度学习的概念和AI计算框架的角色( https://zhuanlan.zhihu.com/p/463019160 ),本篇文章将演示怎么利用MindSpore来训练一个AI模型。和上一章的场景一致,我们要训练的模型是用来对手写数字图片进行分类的LeNet5模型 请参考( http://yann.lecun.com/exdb/lenet/ )。 图1 M

    2024年02月04日
    浏览(40)
  • 手把手教你做一个多路灰度传感器

    市面上有的灰度传感器对于一些人来说可能不合适  于是呢不少人想自己做,比如我,当时也是走了一些弯路的,现在把自己的经验写上来,各位动手能力强的自己拿去用 原理: 左边发射红外光,地面反射到光敏三极管,改变A_OUTx处的电压值,不同颜色和材质对反射回来的

    2024年02月15日
    浏览(43)
  • 【手把手教你制作一个简易版的shell】

    为了简便,命令行中的提示符我们可以直接用printf打印,而具体执行命令可以交给子进程去做,现在的关键是如何将获得的命令行中的命令切割。我们在学习C语言时提到了strtok函数,正好这个函数可以用来作为切割。 基本框架: 不知道大家注意到了没有,我们从键盘中读取

    2023年04月16日
    浏览(38)
  • 手把手带你配置一个DHCP服务器

    最近部门内部成立一个网络兴趣小组,初衷是通过网络知识学习,在遇到网络问题时能够承担起一个与网络侧同学有效沟通的“连接人”的角色,求学这么多年其实也陆续学了不少的网络相关课程,本科的计算机网络、硕士的高等计网等,不过当时大多都停留在理论层面,趁

    2024年02月05日
    浏览(35)
  • 手把手教你写出第一个C语言程序

    大家好,我是努力学习游泳的鱼。这篇文章将手把手带你写出人生中第一个C语言程序, Hello, World 。在阅读本文之前,建议先百度 visual studio ,在微软官网下载并安装VS的最新版本,安装时记得勾选“C++桌面开发”选项。 2.1 环境 工欲善其事必先利其器,我们需要写C语言代码

    2024年02月10日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包