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浏览器比某些人认识的功能强大得多.您可以自定义浏览体验,使其 ...
随机推荐
- java的几个日志框架log4j、logback、common-logging
开发工作中每个系统都需要记录日志,常见的日志工具有log4j(用的最多),slf4j,commons-loging,以及最近比较流行的logback 以前只是在项目中用log4j,更多的是参考下配置文 ...
- MSDos
一.简介 二.源码 http://www.computerhistory.org/atchm/microsoft-research-license-agreement-msdos-v1-1-v2- ...
- 常用MFC宏
最近我在用MFC开发一个智能家居监控平台的软件(用到了MSCOMM串口通信控件),当我通过在一个对话框类A中定义另一个对话框类B的对象访问B的public成员时,提示不可访问.后来经过多天的向朋友求救 ...
- LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图
#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...
- NC 5系查询引擎做报表
在集团下打开查询引擎管理节点,选中查询设计,鼠标移动到创建,点击文件夹 文件夹名字按需求起,创好文件夹后选中该文件夹后鼠标移动到创建,点击对象. 按需求起好编码和名称 都创建好后,点击SQL手工设计 ...
- Spring 注解原理(三)@Qualifier @Value
Spring 注解原理(三)@Qualifier @Value Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 一.Aut ...
- Spring Boot学习笔记:kafka应用
Kafka作为众多Java消息中间件之一,有诸多优点.本文讲解Kafka的应用.学习一个新的知识点,建议先找一个demo,越简单越好的demo,跑通这个demo,了解大致原理,然后在分析细节,详细了解 ...
- The Django Book第六章(Admin)随笔
要使用Django自带的管理界面,首先得激活- 激活的前提首先在你的项目的seeting目录下的INSTALL_APPS必须有以下的的包 django.contrib.admin django.con ...
- [C#.NET]最简单的实现文本框的水印效果
C#项目开发中在设计登录界面时,经常会遇到TextBox的水印提示要求.这里简单描述一下项目在实现水印提示的过程设置.如下图图1所示. 图1 窗体布局 一.窗体布局(如图1所示) 1. 在窗体中放 ...
- MVCS框架的注意点
1.Service最好用一个接口对应一个service(便于增加扩展方法) 2.除Services和Model外都需继承自各自对应的父类 3.View不要轻易重写Start和Awake方法(含与启动有 ...