Lombok自定义annotation扩展含Intellij插件
Lombok简介
Lombok(https://projectlombok.org/) 提供了以注解的形式为java对象增加属性和方法,这使得原来冗长的java源文件变的简洁(不需要再使用ide去生成getter和setter方法,不过ide需要插件支持才能识别lombok自动添加的getter/setter方法,因为真正的代码其实是在编译阶段添加到子节码文件中的),一些固定模板的代码也可以自动添加,例如生成Logger。详细的原理有很多分析贴,此处不再赘述,有需要可以参见附录中的链接:http://notatube.blogspot.com/2010/11/project-lombok-trick-explained.html
Lombok中自带的注解几乎涵盖了所有冗余的,但总是会有一些需要我们自己定制的需求。
研究内容
最近遇到一个情景,一些JAVA对象都需要一个映射到数据库自增ID的字段,为了避免代码冗余,让他们继承自同一个包含同一个id字段的父类似乎就可以解决问题,不同的主键还有可能是不同的数据类型,较常见的是Long,Integer和String(uuid),所以这个父类需要写成一个模板类,并且要求所有包含主键的类都要继承这个泛型父类,其实我们只是想要的只是这个类增加一个id字段,并且生成对应的getter和setter 方法就好了,与其搞成继承关系,倒不如让效法lombok,使用annotation来生成这个字段和方法。
本文探讨的内容包括:
新增一个PrimaryKey注解,接受keyName和keyType两个参数,凡是有PrimaryKey注解的类,都会自动生成一个类型是${keyType}、字段名为${keyName}的字段,并为这个字段生成getter和setter方法。
让intellij的lombok插件能够识别新的注解,可以自动提示主键字段和它的getter/setter方法,而不报编译错误
自定义注解
不仅要新建自定义注解,还要新建对应的Handler,以便编译阶段正确处理包含自定义注解的源文件。
开发环境设置
首先checkout最新的lombok代码,https://github.com/rzwitserloot/lombok.git
lombok项目目前只有基于Eclipse的debug环境配置脚本,如果是Intellij,需要自己配置一下lombok的环境,稍后会介绍。
工程中有基于ant的自动构建脚本,先运行"compile" 任务,这时会自动触发"ensureBuildDeps"这个任务,它会下载一些依赖的Jar包。Tips:中间会去下一个对应jdk版本的rt.jar文件,由于这个文件比较大,国内下载速度非常慢,建议自行翻|墙下载,放到lib目录对应java版本的文件夹下面即可。
编译成功之后,就可以跑一下"test"任务了,它会先执行"dist",在dist目录下面生成lombok的jar文件,然后执行自动测试。
新建自定义注解
注解类代码如下:
package lombok; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 默认以Long作为主键类型
* Created by hoyt on 15/9/22.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface PrimaryKey {
Class keyType() default Long.class;
String keyName() default "id";
}
新建HandlePrimaryKey
handler需要继承自JavacAnnotationHandler,并实现其handle方法,简述一下handle方法里的操作
判断目标注解(这里就是PrimaryKey)是否满足正确性验证
验证通过时,为被注解的类动态添加字段,字段的名称和类型都是PrimaryKey注解中的值
为新添加的字段创建getter和setter方法
handle方法的声明如下:
public void handle(AnnotationValues<PrimaryKey> annotation, JCTree.JCAnnotation ast, JavacNode annotationNode){
}
其中,annotation是lombok自定义的类型,包含了自定义的注解信息,通过如下代码,就可以获得注解中设置的具体值
String keyName = annotation.getInstance().keyName();
Class pk = annotation.getInstance().keyType();
在新建字段、创建getter/setter方法时,都可以直接复用lombok已有的方法和类,非常方便,贴出部分关键代码。
JCTree.JCExpression keyType = chainDotsString(typeNode, type);
JCTree.JCVariableDecl field = maker.VarDef(
maker.Modifiers(Flags.PRIVATE),
typeNode.toName(keyName), keyType, null);
JCTree.JCVariableDecl fieldDecl = recursiveSetGeneratedBy(field, source, typeNode.getContext()); JavacNode fieldNode = injectFieldAndMarkGenerated(typeNode, fieldDecl); new HandleGetter().generateGetterForField(fieldNode, source.pos(), AccessLevel.PUBLIC, false);
new HandleSetter().generateSetterForField(fieldNode, typeNode, AccessLevel.PUBLIC);
return true;
*如果要支持Eclipse自带的编译器,需要另外写一个handler
测试Handle
幸好lombok已经包含了测试/调试环境配置(只针对eclipse,Intellij需要自行配置)。直接运行"setupJavaOracle8TestEnvironment",就会自动配置好基于junit的测试/调试环境。这时打开"Run Configurations",就会发现Junit的测试里多了一种"RunLombokTest"...如下图所示:
![]()
实际上没有必要跑全部的junit测试,只要跑TestWithDelombok即可
![]()
lombok的单元测试是这样的:在test/transform/resource目录里,有三个文件夹,before,after-delombok和after-ejc,before中是所有测试用的java文件,而after-delombok目录中包含的则是lombok.jar参与编译后生成的java源文件,单元测试时,会将after-delombok中的文件作为expected value去同生成的代码做比较,如果一致就认为通过测试。因此单元测试时,在before目录中创建一个class,并为之加上自定义注解,同时在after-lombok中新建一个同名类,把预期的字段和方法写进去即可。after-ejc用于测试eclipse的java编译器结果。注:lombok在处理字段和方法时,会加上额外的标注注解。
![]()
至于Intellij,做调试相对就麻烦一点,需要打开一个intellij的新实例,新建一个项目,在这个项目中引入修改后的lombok,然后加上自定义的注解,这时会触发原来那个intellij中lombok的代码运行,此时断点就会被触发。
Intellij-lombok插件
自定义的注解已经完成,在javac时指定javaagent为新打包出来的lombok.jar即可,不过蛋疼的是,ide此时尚不能识别自定义的注解,为了能够让集成开发环境与新添加的自定义注解合作无间,还需要对Intellij的lombok插件做一番改造。
今天相关的代码见:https://git.oschina.net/hoyt/lombok.git,明天继续补完Intellij插件的工作。
Lombok自定义annotation扩展含Intellij插件的更多相关文章
- IntelliJ插件安装
1. 插件管理器在线安装 在IntelliJ插件管理页面([FileàSettingsàIDE SettingsàPlugins]),点击[Browse repositories-]按钮,在搜索框内输 ...
- Java程序员必备的Intellij插件
以下是我用过不错的Intellij插件 1. .ignore 地址:https://plugins.jetbrains.com/plugin/7495--ignore 生成各种ignore文件,一键创 ...
- Java程序员必备的Intellij插件(长期更新,截止到2018-05-03)
善用Intellij插件可大幅提升我们的效率 以下是我用过不错的Intellij插件 1. .ignore 生成各种ignore文件,一键创建git ignore文件的模板,免得自己去写 截图: ...
- 善用Intellij插件可大幅提升我们的效率
转自 :https://www.jianshu.com/p/686ba0ae4ac2 1. .ignore 生成各种ignore文件,一键创建git ignore文件的模板,免得自己去写 截图: 2. ...
- (转)Bootstrap 之 Metronic 模板的学习之路 - (6)自定义和扩展
https://segmentfault.com/a/1190000006815041 前面我们将 Metronic 的结构和源码大致浏览了一遍,Metronic 整个文件包有三百多兆,在实际项目中, ...
- intellij 插件的使用
目录 intellij 插件的使用 插件的设置 插件推荐 @(目录) intellij 插件的使用 插件的设置 在 IntelliJ IDEA 的安装讲解中我们其实已经知道,IntelliJ IDEA ...
- 阅读笔记09-Java程序员必备的Intellij插件
1. .ignore 生成各种ignore文件,一键创建git ignore文件的模板,免得自己去写 地址:plugins.jetbrains.com/plugin/7495--ignore 2. l ...
- IDEA报 : Lombok Requires Annotation Processing
Lombok Requires Annotation Processing Annotation processing seems to be disabled for the project &qu ...
- 2022必须拥有Chrome扩展程序 - 浏览器插件,让你上网效率翻倍
在Chrome网上应用店中查找扩展程序 2022必须拥有Chrome扩展程序 - 浏览器插件,让你上网效率翻倍 可扩展的Chrome Web浏览器比某些人认识的功能强大得多.您可以自定义浏览体验,使其 ...
随机推荐
- Centos7上安装docker及使用scrapy-splash
下载docker https://www.cnblogs.com/yufeng218/p/8370670.html 安装scrapy-splash https://www.cnblogs.com/ ...
- 团队合作之项目NABCD
小组组长 :毛松林 组员 :张浩,谢诗语 N 我们小组要开发的项目是“高校自习室查询APP”,作为一个大学生,自学是一件很重要的能力,大学的老师不可能还像高中的老师那样整天逼着你学习,爱学不学,不学 ...
- Java图形化界面设计——GridBagConstraints
JAVA布局模式:GridBagConstraints终极技巧参数详解 布局模式 :GridBagConstraints布局,先发一个实例: gridx = 2; // X2 gridy = 0; / ...
- windows2003服务器,时间每隔1小时自动同步一次
有台服务器的时间总是不对,可能是电池快没电了吧,于是想让它时间保持更新状态,但又不想用第三方软件,在百度上查了一下,还真有方法 HKEY_LOCAL_MACHINE->SYSTEM->Cu ...
- 利用Swoole编写一个TCP服务器,顺带测试下Swoole的4层生命周期
1首先我们写一个入口脚本,这里简单点的功能就是开启服务和关闭服务 <?php //CLI命令 if(isset($argv[1]) && in_array($argv[1], [ ...
- hdu (kruska and prime) 继续畅通工程
题目http://acm.hdu.edu.cn/showproblem.php?pid=1879 复习一下最小生成树的两个基本算法. 由于存在道路是否已修建的问题,如果已修建,那么该条道路的成本即为0 ...
- 20172306《Java程序设计与数据结构》第十周学习总结
20172306<Java程序设计>第十周学习总结 教材学习内容总结 本章主要的讲的是集合有关的知识: 1.集合与数据结构 - 集合是一种对象,集合表示一个专用于保存元素的对象,并该对象还 ...
- serial -1
#include <reg52.h>#include <stdio.h>#define uchar unsigned charsbit LED = P2^2;uchar rec ...
- 基于内存,redis,mysql的高速游戏数据服务器设计架构 ZT
zt http://www.cnblogs.com/captainl1993/p/4788236.html 1.数据服务器详细设计 数据服务器在设计上采用三个层次的数据同步,实现玩家数据的高速获取和 ...
- django网页图片验证码功能
在一个正常的登录系统中,验证码是非常重要的,用于识别人机,毕竟我们都知道,这个世界中存在着万恶的爬虫,验证码有很多种方式,有图片的,有邮件的,有短信的,有拼图的,不管什么样的验证码,目的都是验证访问用 ...