关于lombok:聊聊使用lombok-Builder踩到的坑

前言什么是lombokLombok我的项目是一个Java库,它会主动插入编辑器和构建工具中,Lombok提供了一组有用的正文,用来打消Java类中的大量样板代码。 对lombok不相熟的敌人,能够浏览一下官网文档,再来看本文。官网文档如下 https://projectlombok.org/ 注释咱们先来看一个小例子 发问: main函数会输入什么? 答案:空指针异样 Exception in thread "main" java.lang.NullPointerException at com.github.lybgeek.msg.test.User.addPositionList(User.java:25) at com.github.lybgeek.msg.test.User.main(User.java:30)答复出正确答案的敌人,下文基本上能够不必看了。可能有些敌人会有疑难,我例子中明明应用了 private List<String> positionList = new ArrayList<>();为什么还会报空指针? 假相就在lombok用@builder生成的class文件中,咱们看下应用@builder,生成的class文件反编译后长啥样 看到我圈红起来的,大家应该就高深莫测。原来当咱们用 User user = User.builder().username("张三").build();时,此时user对象中的positionList就会被userBuilder中的positionList笼罩,而userBuilder中的positionList是null 如何解决办法一:positionList后面加上final润饰 private final List<String> positionList = new ArrayList<>();此时用@Budiler生成class为此时user对象中的positionList用的还是原先的positionList,因而不会呈现空指针异样 办法二:positionList后面加上@Builder.Default注解 @Builder.Default private List<String> positionList = new ArrayList<>();此时用@Budiler生成class为 public static class UserBuilder { private String username; private boolean positionList$set; private List<String> positionList; UserBuilder() { } public User.UserBuilder username(final String username) { this.username = username; return this; } public User.UserBuilder positionList(final List<String> positionList) { this.positionList = positionList; this.positionList$set = true; return this; } public User build() { List<String> positionList = this.positionList; if (!this.positionList$set) { positionList = User.$default$positionList(); } return new User(this.username, positionList); }当positionList$set为false,会给userBuilder的positionList赋值为 ...

September 14, 2021 · 1 min · jiezi

关于lombok:lombok自定义入参校验

咱们应用一个Vo接支出参,如果咱们想通过lombok定义好每个参数的校验,以及校验提醒,则能够参考如下。留神:应用 Hibernate-Validated 进行校验,要应用则必须在类上增加 @Validated 注解,否则是不会失效的 @Datapublic class RequestVo { @ApiModelProperty("作者姓名") @NonNull @Length(min = 1, max = 10, message = "姓名长度必须小于十个字符") private String authorName; @ApiModelProperty("作者年龄") @NonNull @Range(min = 1, max = 8, message = "作者年龄必须小于8岁") private Integer authorAge;}参考链接:https://www.cnblogs.com/xluck...

May 7, 2021 · 1 min · jiezi

关于lombok:springboot-工程下lombok的应用

背景剖析在理论的java我的项目中咱们创立的所有pojo类简直都要为属性增加set/get/toString等相干办法,所有的日志记录相干类可能都要创立日志等对象,这些样板代码既没有技术含量,又影响着代码的好看,同时反复的编码过程会在无形中加大咱们的工作量。 此时Lombok应运而生。 lombok简介概述Lombok是一个第三的Java库,它会主动插入编辑器和构建工具中,Lombok提供了一组有用的正文,用来通知编译过程中的编译工具,在源代码编译成字节码的过程中,在字节码中增加一些量样板代码。 罕用注解剖析@Setter 用于为形容的类生成setter办法,不蕴含final润饰属性。@Getter 用于为形容的类生成getter办法。@ToString 用于为形容的类增加toString办法。@EqualsAndHashCode 用于为形容的类,生成hashCode和equals办法。@NoArgsConstructor 用于为形容的类生成无参的构造方法。@AllArgsConstructor 用于为形容的类生成蕴含类中所有字段的构造方法。@Data用于为形容的类生成setter/getter、equals、canEqual、hashCode、toString办法,如为final属性,则不会为该属性生成setter办法。@Slf4J 用于为形容的类增加一个日志属性对象。lombok装置idea中的装置配置第一步:关上idea的设置窗口,找到plugins菜单,搜寻lombok进行装置,如图所示: 第二步:启动注解解决,如图所示: 第三步:重启idea(可选,有的idea版本须要)。 sts中的装置配置本人百度尝试。 lombok在maven我的项目中利用第一步:增加lombok依赖。 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>annotationProcessor</scope></dependency>第二步:在类上利用lombok注解。 @Data @NoArgsConstructor @AllArgsConstructor public class Goods { private Long id; private String name; private String remark; private Date createdTime;}第三步:编写单元测试类检测Lombok注解利用 @Slf4j@SpringBootTestpublic class GoodsTests{ @Test void testGoods(){ Goods g=new Goods(); g.setId(100L); g.setName("Lombok"); log.info("id的值为{}",g.getId()); log.info("name的值为{}",g.getName()); }}总结(Summary)本大节次要对lombok做了一个剖析,装置和配置,并结合实际我的项目解说了lombok的利用场景及具体利用过程。

December 8, 2020 · 1 min · jiezi

关于lombok:新来的老大说公司以后禁止使用Lombok我表示反对

常常在其它各个中央在说公司禁止应用Lombok,我始终不明确为什么不让用,明天看到一篇文章列举了一下“毛病”,这里我只想狠狠地反驳,看到列举的理由我竟无言以对。 JDK 版本问题 当我想要将现有我的项目的 JDK 从 Java 8 降级到 Java 11 时,我发现 Lombok 不能失常工作了。于是我不得不将所有的 Lombok 注解从我的项目源代码中革除,并应用 IDE 自带的性能生成 getter/setter,equals,hashCode,toString 以及结构器等办法,你也能够应用 Delombok 工具实现这一过程。但这终究会耗费你很多的工夫。 我的反驳:很多公司一旦确定JDK版本在很长的工夫都不会扭转(比方银行我的项目很多都在用jdk1.6,你问他违心降级到jdk11不?),当初都出到14版本了,你看有多少公司会降级!如当初很多公司都在用JDK1.8,任你出到JDK14,我仍然持续应用JDK1.8,等你出到JDK20时我置信Lombok必定会反对更高的版本,那时兼容问题将不存在。 胁迫应用 当你的源代码中应用了 Lombok,恰好你的代码又被其余的人所应用,那么依赖你代码的人,也必须装置 Lombok 插件 (不论他们喜不喜欢),同时还要破费工夫去理解 Lombok 注解的应用状况,如果不那么做,代码将无奈失常运行。应用过 Lombok 之后,我发现这是一种很流氓的行为。 我的反驳:你装不装Lombok 插件不是你喜不喜欢,不是由你集体志愿决定的,这是工作,公司要求怎么做就要怎么做,这是规定。Lombok是一个非常简单的知识点,十分钟就能上手应用,你却埋怨要花费工夫学习,作为程序员不是无时无刻都在学习吗,你有这种埋怨只能你放弃程序员这个工作吧! 可读性差 Lombok 暗藏了 JavaBean 封装的细节,如果你应用 @AllArgsConstructor 注解,它将提供一个巨型结构器,让外界有机会在初始化对象时批改类中所有的属性。 首先,这是极其不平安的,因为类中某系属性咱们是不心愿被批改的; 另外,如果某个类中有几十个属性存在,就会有一个蕴含几十个参数的结构器被 Lombok 注入到类中,这是不理智的行为; 其次,结构器参数的程序齐全由 Lombok 所以制,咱们并不能操控,只有当你须要调试时才发现有一个奇怪的 “小强” 在等着你; 最初,在运行代码之前,所有 JavaBean 中的办法你只能设想他们长什么样子,你并不能看见。 我的反驳:不称心@AllArgsConstructor的做法你能够应用@Builder啊,这个反对你任意程序任意数量的创建对象,你不理解Lombok的其它用法就说它不好。你要看JavaBean中的办法?它有啥难看的,Getter和Setter办法有啥难看的,你不晓得Getter和Setter办法长什么样吗?切实不明确有什么难看的? 代码耦合度减少 当你应用 Lombok 来编写某一个模块的代码后,其余依赖此模块的其余代码都须要引入 Lombok 依赖,同时还须要在 IDE 中装置 Lombok 的插件。 尽管 Lombok 的依赖包并不大,但就因为其中一个中央应用了 Lombok,其余所有的依赖方都要强制退出 Lombok 的 Jar 包,这是一种入侵式的耦合,如果再遇上 JDK 版本问题,这将是一场劫难。我的反驳:咱们在应用其它框架时,那框架引入了成千上万的包,当初要引入一个很小的包都在宽宏大量,Lombok这么好用,简直所有我的项目都会应用到,这还须要强制引入吗,咱们盲目的都会在maven的parent依赖中对立引入了。 ...

November 25, 2020 · 1 min · jiezi

关于lombok:今天-1024为了不-996Lombok-用起来以及避坑指南

Lombok简介、应用、工作原理、优缺点Lombok 我的项目是一个 Java 库,它会主动插入编辑器和构建工具中,Lombok 提供了一组有用的注解,用来打消 Java 类中的大量样板代码。 @[TOC] 简介官网介绍 Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again, with one annotation your class has a fully featured builder, automate your logging variables, and much more.翻译之后就是: Lombok 我的项目是一个 Java 库,它会主动插入您的编辑器和构建工具中,简化您的 Java 。 不须要再写另一个 getter、setter、toString 或 equals 办法,带有一个正文的您的类有一个性能全面的生成器,能够自动化您的日志记录变量,以及更多其余性能 官网链接 应用增加maven依赖<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> <scope>provided</scope></dependency>留神: 在这里 scope 要设置为 provided, 避免依赖传递给其余我的项目 ...

October 24, 2020 · 7 min · jiezi

关于lombok:Lombok应用配置

Lombok:是一个第三库,能够基于lombok中提供的API,在程序编译时主动织入一些办法。这样做的话能够简化咱们对某些办法的编写,例如,省略pojo类中的set办法,get办法,toString等办法的编写。咱们写的java程序能够在编译时,通过lombok主动将这些办法增加到.class文件中,** 第一步:增加依赖<dependency<groupId>org.projectlombok</groupId<artifactId>lombok</artifactId</dependency 补充:1.在sts里能够下载依赖,然而须要本人装置lombok2.idea里只有下载插件在下载依赖就能够了 第二步:找到下载的lombok-xxx.jar依赖所在的地位

September 27, 2020 · 1 min · jiezi

Gradle项目引入Lombok

接前面一篇文章 《Lombok常用注解的使用总结》 这里主要讲解,如何在Gradle项目中引入Lombok依赖。 以上,Lombok官网提供了两种方式: Lombok Gradle插件添加Lombok依赖我们使用第二种方式,先对Gradle的两个内置作用域做简单说明: compileOnly:只编译时有效,不参与打包。代替旧版本的provided annotationProcessor:管理注解处理器,并将其添加到处理器类路径中重点来了,是否所有Gradle版本都支持官网这种写法呢? 答案是否定的。 Gradle 5.0及以上版本:annotationProcessor 'org.projectlombok:lombok:1.18.8'Gradle 5.0版本以下:compileOnly 'org.projectlombok:lombok:1.18.8'Diboot - 简单高效的轻代码开发框架

June 25, 2019 · 1 min · jiezi

Lombok

官网链接:https://projectlombok.org/ 什么是 LombokLombok 是一个 Java 库,它可以通过添加注解的方式,为 Java 类自动插入相应的 Getter/Setter,构造器,equals 方法等。这样就省去了手动重建代码的麻烦,简化开发,也是代码更为简洁。 当然,Lombok 也支持使用注解为 Java 类添加 Builder,自动注入日志记录变量等。 为什么使用 Lombok (优劣)优点 显然,使用 Lombok 可以大量减少项目中的模版代码。虽然开发过程中可以通过 IDE 快速生成这些代码,但当 Java 类的变量发生变化,或者协作开发过程中有代码冲突,这无疑增加了我们无谓的工作量。 其次,Lombok 还可以增强代码的规范性,通过 @Data 注解可以自动添加包括 toString 在内的模版方法,避免了这些方法缺失,也省去了因变量修改而修改 toString,equals 方法的麻烦。 缺点 Lombok 的项目集成和使用,它需要 IDE 和项目都要支持。不过这不麻烦。 安装IntelliJ IDEA 打开 File/Setting 或 快捷键 Ctrl+Alt+S选择 Plugins搜索插件 IntelliJ Lombok plugin 并安装重启 IDEA 即完成STS/Eclipse 下载 lombok.jar将 lombok.jar 放在sts(eclipse)安装目录下,和 sts.ini 文件平级的在lombok.jar 的目录下,运行:java -jar lombok.jar,在弹出框中指定 STS/Eclipse 安装目录,点击安装查看 sts.ini,正常情况应该多个一行配置:-javaagent:XXX\lombok.jar依赖添加 <lombok.version>1.18.6</lombok.version><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope></dependency>使用介绍按使用频率从上及下排列 ...

April 28, 2019 · 1 min · jiezi

使用Lombok-Builder后代码详解

前提我们有一个学生类: @Builderpublic class Student { // 该字段有一个默认值; private int status = 1;}public class Test { @Test public void testBuilder() { // 生成的student对象并没有使用status的默认值 Student student = Student.builder().build(); }}为什么@Builder没有使用到默认值?使用@Builder之后会生成一个静态内部类StudentBuilder,编译之后我们可以看到一共存在2个class文件。 将Student.class与StudentBuilder.class反编译之后的diamante如下 public class Student { private int status = 1; // 注意:此处lombok生成了一个全参的构造函数 Student(int status) { this.status = status; } public static StudentBuilder builder() { return new StudentBuilder(); }}public class Student$StudentBuilder { private int status; public Student$StudentBuilder status(int status) { this.status = status; return this; } public Student build() { return new Student(this.status); } public String toString() { return "Student.StudentBuilder(status=" + this.status + ")"; }}在StudentBuilder代码的build()方法中可以看出来,生成Student对象时的status字段值是StudentBuilder中的status字段值。所以如果不通过status(int status)方法显式的设置status字段的话,最终生成的对象中的status值是java中int的默认值0,而不是在Student类中规定的默认值1 ...

April 23, 2019 · 1 min · jiezi

Lombok使用注意事项

今天发现线上数据的某个字段被莫名更改了,找了一下原因,才发现使用lombok有很多注意事项。接下来一一讲述 @Builder注意事项类中字段默认值不会被直接使用我们有个学生类代码如下:其中学生类有一个stuStatus字段表示学生就读状态,默认值1,表示默认是在读状态。当通过builder()构建学生对象之后,如果不给stuStatus赋值,该字段的值并不是默认值1,而是int的默认值0; @Data@Builderpublic class Student { // 学生学号 private String stuNumber; // 学生姓名 private String stuName; // 学生状态(1:在读 2:离校) 默认是1,表示在读状态 private int stuStatus = 1;}public class TestStudent() { @Test public void testBuilder() { // 以下代码构建完成之后,student的stuStatus字段并不是默认值1,而是int的默认值0; Student student = Student.builder().build(); // Student{stuNumer:null,stuName:null,stuStatus:0} }}为什么出现这种情况呢?因为lombok在builder()的时候如果没有显示的给字段赋值,那么这个字段的值就是java中的默认值(int:0 String:null这种的),即使在类中给字段设置默认值也不生效。 如何解决呢? 在字段上使用@Builder.Default注解。 @Data@Builderpublic class Student { // 学生学号 private String stuNumber; // 学生姓名 private String stuName; // 学生状态(1:在读 2:离校) 默认是1,表示在读状态 // import lombok.Builder.Default; 或者使用@Builder.Default @Default private int stuStatus = 1;}public class TestStudent() { @Test public void testBuilder() { // 以下代码构建完成之后,student的stuStatus字段就是默认值1 Student student = Student.builder().build(); // Student{stuNumer:null,stuName:null,stuStatus:1} }}Lombok@Builder代码分析在line110 ~ line 115可以发现一个@Default注解。注释的意思就是:使用@Default注释的字段需要有一个初始化表达式(即我们字段的默认值),如果在生成期间没有显式的给该字段set值,则采取该值。 ...

April 23, 2019 · 1 min · jiezi

手撸lombok

拥抱 lombok,它会帮助我们解决一些让我们很烦躁的问题去掉 Setter 和 Getter @Setter @Getter public class UserDTO { @NotNull private String username; @NotNull private int age; public User convertToUser(){ UserDTOConvert userDTOConvert = new UserDTOConvert(); User convert = userDTOConvert.convert(this); return convert; } public UserDTO convertFor(User user){ UserDTOConvert userDTOConvert = new UserDTOConvert(); UserDTO convert = userDTOConvert.reverse().convert(user); return convert; } private static class UserDTOConvert extends Converter<UserDTO, User> { @Override protected User doForward(UserDTO userDTO) { User user = new User(); BeanUtils.copyProperties(userDTO,user); return user; } @Override protected UserDTO doBackward(User user) { throw new AssertionError(“不支持逆向转化方法!”); } } }看到了吧,烦人的 Getter 和 Setter 方法已经去掉了。bean 中的链式风格改造前public class Student { private String name; private int age; public String getName() { return name; } public Student setName(String name) { this.name = name; return this; } public int getAge() { return age; } public Student setAge(int age) { return this; }}相信合理使用这样的链式代码,会更多的程序带来很好的可读性,那看一下如果使用 lombok 进行改善呢,请使用 @Accessors(chain = true),看如下代码:@Accessors(chain = true)@Setter@Getterpublic class Student { private String name; private int age;}这样就完成了一个对于 bean 来讲很友好的链式操作。静态构造方法静态构造方法的语义和简化程度真的高于直接去 new 一个对象。比如 new 一个 List 对象,过去的使用是这样的:List<String> list = new ArrayList<>();看一下 guava 中的创建方式:List<String> list = Lists.newArrayList();Lists 命名是一种约定(俗话说:约定优于配置),它是指 Lists 是 List 这个类的一个工具类,那么使用 List 的工具类去产生 List,这样的语义是不是要比直接 new 一个子类来的更直接一些呢,答案是肯定的,再比如如果有一个工具类叫做 Maps,那你是否想到了创建 Map 的方法呢:HashMap<String, String> objectObjectHashMap = Maps.newHashMap();接上上边的静态构造方法和必传参数的构造方法,使用 lombok 将更改成如下写法(@RequiredArgsConstructor 和 @NonNull):@Accessors(chain = true)@Setter@Getter@RequiredArgsConstructor(staticName = “ofName”)public class Student { @NonNull private String name; private int age;}测试代码:Student student = Student.ofName(“zs”);这样构建出的 bean 语义是否要比直接 new 一个含参的构造方法(包含 name 的构造方法)要好很多。当然,看过很多源码以后,我想相信将静态构造方法 ofName 换成 of 会先的更加简洁:@Accessors(chain = true)@Setter@Getter@RequiredArgsConstructor(staticName = “of”)public class Student { @NonNull private String name; private int age;}测试代码:Student student = Student.of(“zs”);当然他仍然是支持链式调用的:Student student = Student.of(“zs”).setAge(24);这样来写代码,真的很简洁,并且可读性很强。使用 builder@Builderpublic class Student { private String name; private int age;}调用方式:Student student = Student.builder().name(“zs”).age(24).build();代理模式正如我们所知的,在程序中调用 rest 接口是一个常见的行为动作,如果你和我一样使用过 spring 的 RestTemplate,我相信你会我和一样,对他抛出的非 http 状态码异常深恶痛绝。所以我们考虑将 RestTemplate 最为底层包装器进行包装器模式的设计:public abstract class FilterRestTemplate implements RestOperations { protected volatile RestTemplate restTemplate; protected FilterRestTemplate(RestTemplate restTemplate){ this.restTemplate = restTemplate; } //实现RestOperations所有的接口}然后再由扩展类对 FilterRestTemplate 进行包装扩展:public class ExtractRestTemplate extends FilterRestTemplate { private RestTemplate restTemplate; public ExtractRestTemplate(RestTemplate restTemplate) { super(restTemplate); this.restTemplate = restTemplate; } public <T> RestResponseDTO<T> postForEntityWithNoException(String url, Object request, Class<T> responseType, Object… uriVariables) throws RestClientException { RestResponseDTO<T> restResponseDTO = new RestResponseDTO<T>(); ResponseEntity<T> tResponseEntity; try { tResponseEntity = restTemplate.postForEntity(url, request, responseType, uriVariables); restResponseDTO.setData(tResponseEntity.getBody()); restResponseDTO.setMessage(tResponseEntity.getStatusCode().name()); restResponseDTO.setStatusCode(tResponseEntity.getStatusCodeValue()); }catch (Exception e){ restResponseDTO.setStatusCode(RestResponseDTO.UNKNOWN_ERROR); restResponseDTO.setMessage(e.getMessage()); restResponseDTO.setData(null); } return restResponseDTO; }}包装器 ExtractRestTemplate 很完美的更改了异常抛出的行为,让程序更具有容错性。在这里我们不考虑 ExtractRestTemplate 完成的功能,让我们把焦点放在 FilterRestTemplate 上,“实现 RestOperations 所有的接口”,这个操作绝对不是一时半会可以写完的,当时在重构之前我几乎写了半个小时,如下:public abstract class FilterRestTemplate implements RestOperations { protected volatile RestTemplate restTemplate; protected FilterRestTemplate(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @Override public <T> T getForObject(String url, Class<T> responseType, Object… uriVariables) throws RestClientException { return restTemplate.getForObject(url,responseType,uriVariables); } @Override public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { return restTemplate.getForObject(url,responseType,uriVariables); } @Override public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException { return restTemplate.getForObject(url,responseType); } @Override public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object… uriVariables) throws RestClientException { return restTemplate.getForEntity(url,responseType,uriVariables); } //其他实现代码略。。。}我相信你看了以上代码,你会和我一样觉得恶心反胃,后来我用 lombok 提供的代理注解优化了我的代码(@Delegate):@AllArgsConstructorpublic abstract class FilterRestTemplate implements RestOperations { @Delegate protected volatile RestTemplate restTemplate;}这几行代码完全替代上述那些冗长的代码。是不是很简洁,做一个拥抱 lombok 的程序员吧。 ...

April 20, 2019 · 3 min · jiezi

使用神器Lombok优雅编码

Lombok介绍近来偶遇一款撸码神器,介绍给大家~相信许多小伙伴都深有体会,POJO类中的千篇一律的getter/setter,constructor等方法让人写的揪心,那么今天就有一种方法可以残暴的解决这个问题。接下来为大家介绍这款神器:Lombok以下是官方对Lombok的介绍Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.Project Lombok是一个java库,它可以自动插入编辑器和构建工具,为java增色。永远不要再编写另一个getter或equals方法,使用一个注释,您的类就有了一个功能齐全的构建器、自动记录变量等等。简而言之,Lombok实现的效果就是通过简单的注解来精简代码达到消除冗长代码的目的。Lombok优点及缺点对Lombok有了一个基本的认识之后,让我们来挖掘一下它的优缺点。首先看一下它的优点。提高编码效率使代码更简洁消除冗长代码避免修改字段名字时忘记修改方法名提高下逼格以上就是Lombok的优点,当然,Lombok的优点远远不止以上几点,使用Lombok,你可以更加优雅高效的编辑代码。但,俗话说“有利必有弊”,Lombok为我们带来便利的同时也带来的不少小麻烦。Lombok需要额外的环境配置(接下来为讲到)传染性(一旦在resource包里用了lombok,别人想看源码也不得不装插件)降低代码可读性虽然Lombok有着不少缺点,但总归是利大于弊,作为一款优秀的神器,仍然值得我们去学习。Lombok原理授人以鱼不如授人以渔,接下来简要介绍一下Lombok的原理。Sun公司在2005.2.1提交了JSR 269,用于支持在编译期对annotation进行处理,即引入了插入式注解处理API(Pluggable Annotation Processing API)。javac从java6开始支持“JSR 269 API”规范,只要程序实现了该API,就能在javac运行的时候得到调用,而Lombok实现了“JSR 269 API”,在编译时,javac编译源码的具体流程如下:Source File -> Parse -> AST -> Annotation Processing -> Modified AST -> Analyze and Generate -> Byte CodeLombok引入项目引入Lombok jar包在项目中引入Lombok的方法有很多,在此以Maven为例进行讲解,其他途径可以参考官方网站https://projectlombok.org/。打开pom.xml文件,添加以下依赖。<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope></dependency>IDEA/Eclipse安装Lombok插件在上面提到,Lombok需要额外的环境配置,此处以IDEA为例进行讲解。第一步,打开File -> Settings -> Plugins,输入Lombok Plugin点击搜索。第二步,重启IDE使插件生效。Lombok实战Coding完成了上述准备之后,就可以愉快的使用Lombok进行编码了。编码之前首先为大家介绍一下Lombok的基本用法。@Data包含了 @Getter @Setter @ToString @EqualsAndHashCode即自动为类生成所有getter、setter、toString、eaquals以及hashCode方法@Getter 为所有属性生成public修饰的get方法@Getter(AccessLevel.PROTECTED) 为所有属性生成protected修饰的get方法@Setter 为所有属性生成public修饰的set方法@Setter(AccessLevel.PROTECTED) 为所有属性生成protected修饰的set方法@NoArgsConstructor 无参构造器@AllArgsConstructor 生成带有所有属性的有参构造器@ToString 默认生成带有所有属性的toString方法@ToString(exclude = “column”) 生成除column属性之外的所有属性的toString方法@ToString(exclude = {“column1”, “column2”}) @ToString(of = “column”) 生成只有column属性的toString方法@ToString(of = {“column1”, “column2”})@EqualsAndHashCode@EqualsAndHashCode(exclude = “column”) 以column属性之外的属性作为是否是相同对象判断的标准@EqualsAndHashCode(of = “column”)) 只以column属性作为是否是相同对象判断的标准@Slf4j 为当前类生成日志对象@Log4j 为当前类生成日志对象接下来让我们简单对比一下代码。首先是未经简化的代码。public class User { private Integer id; private String username; private String password; private String email; private String phone; public User(Integer id, String username, String password, String email, String phone) { this.id = id; this.username = username; this.password = password; this.email = email; this.phone = phone; } public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return Objects.equals(id, user.id) && Objects.equals(username, user.username) && Objects.equals(password, user.password) && Objects.equals(email, user.email) && Objects.equals(phone, user.phone); } @Override public int hashCode() { return Objects.hash(id, username, password, email, phone, question, answer, role, createTime, updateTime); }}接下来是使用Lombok简化后的代码。@Getter@Setter@NoArgsConstructor@AllArgsConstructorpublic class User { private Integer id; private String username; private String password; private String email; private String phone;}Lombok的更多用法,在此不再赘述,等待大家去慢慢发掘。Lombok工作中需要注意的点Lombok虽然好用,但推荐大家选择适合的地方使用Lombok,例如POJO是一个好地方,因为POJO很单纯。彩蛋反编译大法如果有小伙伴想要深究Lombok是如何实现插入式注解的,可以利用反编译大法查看源码。在此推荐另一款神兵利器 Java Decompiler。官方网站为:http://java-decompiler.github.io/有以下三种安装方式:JD-GUI 图形化客户端JD-Eclipse eclipse插件JD-IntelliJ idea插件安装完成后可以通过Java Decompiler验证Class文件。 ...

March 11, 2019 · 2 min · jiezi

Lombok常用注解的使用总结

Lombok是什么?一个在编译阶段修改增强Java类的工具,使用方式基于注解,常用于:为Java POJO生成属性对应的getter,setter等为Java POJO生成builder构造器模式的实现为Java类自动添加其他重复性代码,比如日志记录的声明代码可以通过@Slf4j注解添加项目中是否引入Lombok一直是个存在争议,它的主要优势在于消除Java类的部分臃肿代码,提高开发效率,降低代码维护成本;缺点是需要IDE插件支持,需要团队统一规范,另外某些注解生成的隐性实现可能导致问题跟踪调试困难。不使用Lombok,IDE也可以自动生成getter,setter代码,但Lombok除了getter,setter还有@Builder和@SuperBuilder等非常实用的自动实现。比如你可以将一个POJO类转化为builder模式,如果你又有一个子类,子类的构造器还要继承自父类,写起来就费劲了。而通过Lombok只需要一个@SuperBuilder注解(v1.18.2+版本支持)。如何引入Lombok引入依赖,以gradle为例:compile(“org.projectlombok:lombok:1.18.4”)IDE中安装插件,以IDEA为例: Settings -> Plugins -> 搜索Lombok Plugin,点击安装IDEA中配置启用注解的处理: Enable annotation processing (不开启将导致编译错误)Lombok常见用法在属性上添加的注解: @Getter、@Setter、@NonNull等:示例代码:public class Parent { // get,set添加在指定属性上 @Getter @Setter private int id; @Getter @Setter private String name;}在类上添加的注解:- @Data 注解组合,含@Setter、@Getter、@RequiredArgsConstructor、@EqualsAndHashCode等注解- 构造函数注解: @NoArgsConstructor、@AllArgsConstructor、@RequiredArgsConstructor- 构造器builder注解: @Builder、@SuperBuilder- 日志声明的注解: @Slf4j 等示例代码:@Datapublic class Child extends Parent { private String ext;}@Setter@Getter或@Data注解添加后可以通过new创建对象并调用getter,setter方法:Child c1 = new Child();c1.setId(1); System.out.println(c1.getId());Builder构造器模式与继承构造模式的链式调用写起来很方便,自己实现构造模式要在POJO类中写较多代码,尤其是需要继承父类的builder时。Lombok的@Builder注解可以方便的支持构造模式示例代码:@Builderpublic class Child extends Parent { private String ext;}调用方法:Child c1 = Child.builder().ext(“子类属性ext”).build();System.out.println(c1.getExt());此例中的链式调用仅有ext()属性,即使给父类Parent也添加@Builder注解也依然不能链式调用id()和name(),自己去写builder的实现也是这样,类是继承的,但类中的builder并无继承关系,而实际开发场景中我们一般都需要让子类的builder继承父类builder的行为。Lombok在v1.18.2版本中针对这个问题增加了@SuperBuilder注解,子类和父类中都添加@SuperBuilder注解,子类builder即可继承父类builder。代码示例:@SuperBuilderpublic class Parent { // get,set添加在指定属性上 @Getter @Setter private int id; @Getter @Setter private String name;}@SuperBuilder@Datapublic class Child extends Parent { private String ext;}调用示例:Child c1 = Child.builder().id(1).name(“名称”).ext(“子类属性ext”).build();System.out.println(c1.getId());需要注意的是: 关于builder的继承,Lombok Plugin尚未更新支持@SuperBuilder,所以以上写法在IDE下还会提示编译错误,等更新吧,或者用稍微蹩脚一点的解决方案:Lombok’s @Builder annotation and inheritancediboot轻代码开发平台, diboot开发助理 ...

December 20, 2018 · 1 min · jiezi

java效率工具 Lombok

Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toStringm异常处理,I/O流的关闭操作等等,这些样板代码既没有技术含量,又影响着代码的美观,Lombok应运而生。Lombok是以注解的方式减少了代码量,虽说 IDEA 的插件可以自动生成 get/set/toString 方法,但是使用 Lombok 可以让代码更简洁。IDEA安装插件打开 IDEA 的 Settings 面板选择 Plugins 选项,然后点击 “Browse repositories”在输入框输入”lombok”,得到搜索结果,点击安装,然后安装提示重启 IDEA,安装成功Eclipse的Lombok插件安装可自行谷歌百度项目中引入依赖在自己的项目里添加 lombok 的编译支持,在 pom 文件里面添加以下代码<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope></dependency>scope=provided,说明它只在编译阶段生效,不需要打入包中。事实正是如此,Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件。怎么用主要注解@Getter 生成成员变量的getter方法@Setter 生成成员变量的getter方法@NoArgsConstructor 生成无参构造器@RequiredArgsConstructor 生成包含final和@NonNull注解的成员变量的构造器@EqualsAndHashCode 生成覆盖默认的equals和hashCode@ToString 生成覆盖默认的toString()方法@Data 以上注解的集合:@ToString @EqualsAndHashCode @Getter @Setter @NoArgsConstructor@Log4j 生成log4j日志变量@AllArgsConstructor 生成全参构造器@NonNull 作用于成员变量和参数中,标识不能为空,否则抛出空指针异常@Cleanup 自动关闭资源@SneakyThrows 检异常进行捕捉并抛出@Synchronized 替换synchronize关键字或lock锁重要注解详解@Getter注解在[属性]上:为单个属性提供 get 方法; 注解在[类]上,为该类所有的属性提供 get 方法;都提供默认构造方法。@Setter注解在[属性]上:为单个属性提供 set 方法; 注解在[类]上,为该类所有的属性提供 set 方法;都提供默认构造方法。@NoArgsConstructor @EqualsAndHashCode @ToString 使用与上类似,不累赘说明@Data注解在[类]上:提供类所有属性的 get 和 set 方法,此外还提供了equals、canEqual、hashCode、toString 方法。看Structrue图可看出@Log4j注解在[类]上:为类提供一个 属性名为 log 的 log4j 日志对象,提供默认构造方法。@Cleanup注解用在[变量]上:保证此变量代表的资源会被自动关闭,针对实现了java.io.Closeable接口的对象有效,如:典型的IO流对象@SneakyThrows注解在[方法]上,可以对受检异常进行捕捉并抛出@SneakyThrows(Exception.class) 的形式指定抛出哪种异常@Synchronized注解在[类方法]或者[实例方法]上,效果和 synchronized 关键字相同区别:锁对象不同对于类方法:synchronized 关键字锁对象为:类的 class 对象@Synchronized锁对象为:私有静态 final 对象 lock对于实例方法:synchronized 关键字锁对象为: this 对象@Synchronized锁对象为:私有 final 对象 lock怎样?看起来不错吧!赶紧用起来!坚持日更:40天推荐阅读:「 神器 」资源管理神器Clover,风一样的效率 致低头族 「 趣图 」程序员极度崩溃的 10 个瞬间 阅读原文查看更多精彩内容您的点赞、转发是对我最大的支持! THANDKSEnd -一个立志成大腿而每天努力奋斗的年轻人伴学习伴成长,成长之路你并不孤单! ...

November 30, 2018 · 1 min · jiezi