Lombok详细教程及idea中lombok插件的安装

一、背景

我们在开发过程中,通常都会定义大量的JavaBean,然后通过IDE去生成其属性的构造器、getter、setter、equals、hashcode、toString方法,当要对某个属性进行改变时,比如命名、类型等,都需要重新去生成上面提到的这些方法,那java中有没有一种方式能够避免这种重复的劳动呢?答案是有,我们来看一下下面这张图,右面是一个简单的JavaBean,只定义了两个属性,在类上加上了@Data,从左面的结构图上可以看到,已经自动生成了上面提到的方法。

 

二、Lombok简介

Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。
官方地址:https://projectlombok.org/
github地址:https://github.com/rzwitserloot/lombok

 

三、Lombok使用

lombok插件的安装

IDEA中添加Lombok插件,File->Setting->Plugins搜索Lombok Plugin,点击install,安装完成后重启IDEA

备注:如果在上述的安装过程中无法自动下载,可以选择本地安装
插件下载地址:https://plugins.jetbrains.com/plugin/6317-lombok-plugin
具体步骤可以参照 https://blog.csdn.net/shmily_lsl/article/details/80689307 博客
我这边自己下载的是2016.3版本的

让idea支持lombok编译

勾选idea的Enable annotation processing选项,该选项在Preference——Build,Execution,Deployment——Compiler——Annotation Processors中

 

在maven项目的pom.xml中添加依赖

<!-- lombok -->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <scope>provided</scope>
</dependency>

 

四、Lombok注解介绍

@Data:注解在类上,将类提供的所有属性都添加get、set方法,并添加、equals、canEquals、hashCode、toString方法
@Setter:注解在类上,为所有属性添加set方法、注解在属性上为该属性提供set方法
@Getter:注解在类上,为所有的属性添加get方法、注解在属性上为该属性提供get方法
@NotNull:在参数中使用时,如果调用时传了null值,就会抛出空指针异常
@Synchronized 用于方法,可以锁定指定的对象,如果不指定,则默认创建一个对象锁定
@Log作用于类,创建一个log属性
@Builder:使用builder模式创建对象
@NoArgsConstructor:创建一个无参构造函数
@AllArgsConstructor:创建一个全参构造函数
@ToStirng:创建一个toString方法
@Accessors(chain = true)使用链式设置属性,set方法返回的是this对象。
@RequiredArgsConstructor:创建对象
@UtilityClass:工具类
@ExtensionMethod:设置父类
@FieldDefaults:设置属性的使用范围,如private、public等,也可以设置属性是否被final修饰。
@Cleanup: 关闭流、连接点。
@EqualsAndHashCode:重写equals和hashcode方法。
@toString:创建toString方法。

下面只是介绍了几个常用的注解,更多的请参见https://projectlombok.org/features/index.html

1、@Getter / @Setter注解

可以作用在类上和属性上,放在类上,会对所有的非静态(non-static)属性生成Getter/Setter方法,放在属性上,会对该属性生成Getter/Setter方法。并可以指定Getter/Setter方法的访问级别。当然了属性上面的Getter和Setter的设置要优先于类上面的

 

2、@EqualsAndHashCode注解

默认情况下,会使用所有非瞬态(non-transient)和非静态(non-static)字段来生成equals和hascode方法,也可以指定具体使用哪些属性。
1). 此注解会生成equals(Object other) 和 hashCode()方法。
2). 它默认使用非静态,非瞬态的属性
3). 可通过参数exclude排除一些属性
4). 可通过参数of指定仅使用哪些属性
5). 它默认仅使用该类中定义的属性且不调用父类的方法
6). 可通过callSuper=true解决上一点问题。让其生成的方法中调用父类的方法。

3、@ToString

生成toString方法,默认情况下,会输出类名、所有属性,属性会按照顺序输出,以逗号分割。

4、@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor

@NoArgsConstructor : 生成一个无参数的构造方法
@AllArgsContructor: ?会生成一个包含所有变量
@RequiredArgsConstructor: 会生成一个包含常量,和标识了NotNull的变量的构造方法。生成的构造方法是私有的private。

5、@Data

@Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。
通过官方文档,可以得知,当使用@Data注解时,则有了@EqualsAndHashCode注解,那么就会在此类中存在equals(Object other) 和 hashCode()方法,且不会使用父类的属性,这就导致了可能的问题。 比如,有多个类有相同的部分属性,把它们定义到父类中,恰好id(数据库主键)也在父类中,那么就会存在部分对象在比较时,它们并不相等,却因为lombok自动生成的equals(Object other) 和 hashCode()方法判定为相等,从而导致出错。
修复此问题的方法很简单:
(1)、使用@Getter @Setter @ToString代替@Data并且自定义equals(Object other) 和 hashCode()方法,比如有些类只需要判断主键id是否相等即足矣。
(2)、 或者使用在使用@Data时同时加上@EqualsAndHashCode(callSuper=true)注解。设置该属性的话需要保证当前类继承了父类

6、@slf4j

相当于在类中书写了 private static final Logger log = LoggerFactory.getLogger(User.class);

 

五、Lombok原理

了解了简单的使用之后,现在应该比较好奇它是如何实现的。整个使用的过程中,只需要使用注解而已,不需要做其它额外的工作,那玄妙之处应该是在注解的解析上。JDK5引入了注解的同时,也提供了两种解析方式

1、运行时解析

运行时能够解析的注解,必须将@Retention设置为RUNTIME,这样可以通过反射拿到该注解。java.lang.reflect反射包中提供了一个接口AnnotatedElement,该接口定义了获取注解信息的几个方法,Class、Constructor、Field、Method、Package等都实现了该接口,大部分开发者应该都很熟悉这种解析方式。

boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
Annotation[] getAnnotations();
Annotation[] getDeclaredAnnotations();

2、编译时解析

编译时解析有两种机制,网上很多文章都把它俩搞混了,分别简单描述一下。

(1)、Annotation Processing Tool

apt自JDK5产生,JDK7已标记为过期,不推荐使用,JDK8中已彻底删除,自JDK6开始,可以使用Pluggable Annotation Processing API来替换它,apt被替换主要有2点原因:
1)、api都在com.sun.mirror非标准包下
2)、没有集成到javac中,需要额外运行
apt的更多介绍可以参见这里

(2)、Pluggable Annotation Processing API

JSR 269,自JDK6加入,作为apt的替代方案,它解决了apt的两个问题,javac在执行的时候会调用实现了该API的程序,这样我们就可以对编译器做一些增强,这时javac执行的过程如下:

 

 

  Lombok就是使用这种方式实现的,有兴趣的话可以去看看其Lombok源码,对应注解的实现都在HandleXXX中,比如@Getter注解的实现是HandleGetter.handle()。还有一些其它类库使用这种方式实现,比如Google Auto、Dagger等等。

六、Lombok初学者使用建议

在刚开始使用Lombok的时候建议大家可以多看看class文件,来加深对你所需要使用注解的理解。


作者:Albert_Yu
链接:https://www.jianshu.com/p/3ce2f0a39df4
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值