乐趣区

关于spring:迷茫了我们到底该不该用lombok

前言

最近上网查资料发现很多人对 lombok 褒贬不一,引起了我的趣味,因为咱们我的项目中也在大量应用lombok,大家不同的观点让我也困惑了几天,明天联合我理论的我的项目教训,说说我的集体倡议。

轻易搜搜就找到了这几篇文章:

这些人倡议应用 lombok,感觉它是一个神器,能够大大提高编码效率,并且让代码更优雅。

在搜寻的过程中,有些文章却又不举荐应用:

这些人感觉它有一些坑,容易给我的项目埋下隐患,咱们到底该听谁的呢?

为什么倡议应用 lombok?

1. 传统 javabean

在没应用 lombok 之前,咱们个别是这样定义 javabean 的:

public class User {

    private Long id;
    private String name;
    private Integer age;
    private String address;

    public User() {}

    public User(Long id, String name, Integer age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {return id;}

    public String getName() {return name;}

    public Integer getAge() {return age;}

    public String getAddress() {return address;}


    public void setId(Long id) {this.id = id;}

    public void setName(String name) {this.name = name;}

    public void setAge(Integer age) {this.age = age;}

    public void setAddress(String address) {this.address = address;}

    @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(name, user.name) &&
                Objects.equals(age, user.age) &&
                Objects.equals(address, user.address);
    }

    @Override
    public int hashCode() {return Objects.hash(id, name, age, address);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

User 类中蕴含了:成员变量、getter/setter 办法、构造方法、equals、hashCode 办法。

咋一看,代码还是挺多的。而且还有个问题,如果 User 类中的代码批改了,比方:age 字段改成字符串类型,或者 name 字段名称批改了,是不是须要同步批改相干的成员变量、getter/setter 办法、构造方法、equals、hashCode 办法全都批改一遍?

兴许有些敌人会说:当初的 idea 十分智能,能够把批改一次性搞定。

没错,然而有更优雅的解决办法。

2.lombok 的应用

第一步,引入 jar 包

  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.4</version>
      <scope>provided</scope>
  </dependency>

第二步,在 idea 中装置插件


留神:如果不依照插件 idea 中就无奈编译应用 lombok 注解的代码。

第三步,在代码中应用 lombok 注解

下面的 User 类代码能够改成这样:

@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class User {

    private Long id;
    private String name;
    private Integer age;
    private String address;
}

so good,代码能够优化到如此简略。User类的主体只用定义成员变量,其余的办法全都交给注解来实现。

如果批改了成员变量名称或者类型,怎么办呢?

@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class User {

    private Long id;
    private String userName;
    private String age;
    private String address;
}

你只用全心全意批改成员变量即可,其余的基本不必操心,几乎太爽了。

更让人兴奋的是,还能进一步优化:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {

    private Long id;
    private String userName;
    private String age;
    private String address;
}

@Data 相当于 @Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor 的汇合。

lombok注解整顿如下:

                  图片起源占小狼

从下面看出应用 lombok 给人最大的感触是代码量显著缩小了,可能无效的晋升开发效率,而代码看起来更优雅,的确是一个不可多得的神器。

lombok 工作原理

java 程序的解析分为:运行时解析 编译时解析

通常咱们通过反射获取类、办法、注解和成员变量就是 运行时解析。然而这种形式效率其实不高,要在程序运行起来能力解析。

这时候编译时解析就体现出它的价值了。

编译时解析又分为:注解处理器(Annotation Processing Tool)
JSR 269 插入式注解处理器(Pluggable Annotation Processing API)

第一种处理器它最早是在 JDK 1.5 与注解(Annotation)一起引入的,它是一个命令行工具,可能提供构建时基于源代码对程序结构的读取性能,可能通过运行注解处理器来生成新的两头文件,进而影响编译过程。

不过在 JDK 1.8 当前,第一种处理器被淘汰了,取而代之的是第二种处理器,咱们一起看看它的解决流程:

Lombok 的底层具体实现流程如下:

  1. javac 对源代码进行剖析,生成了一棵形象语法树(AST)
  2. 编译过程中调用实现了“JSR 269 API”的 Lombok 程序
  3. 此时 Lombok 就对第一步骤失去的 AST 进行解决,找到 @Data 注解所在类对应的语法树(AST),而后批改该语法树(AST),减少 getter 和 setter 办法定义的相应树节点
  4. javac 应用批改后的形象语法树(AST)生成字节码文件,即给 class 减少新的节点(代码块)

为什么倡议不必 lombok?

即便 lombok 是一个神器,然而却有很多人不倡议应用,这又是为什么呢?

1. 强制要求队友装置 idea 插件

这点的确比拟恶心,因为如果应用 lombok 注解编写代码,就要求参加开发的所有人都必须装置 idea 的 lombok 插件,否则代码编译出错。

2. 代码可读性变差

应用 lombok 注解之后,最初生成的代码你其实是看不到的,你能看到的是代码被批改之前的样子。如果要想查看某个 getter 或 setter 办法的援用过程,是十分艰难的。

3. 降级 JDK 对性能有影响

有人把 JDK 从 Java 8 降级到 Java 11 时,我发现 Lombok 不能失常工作了。

4. 有一些坑

  1. 应用 @Data 时会默认应用 @EqualsAndHashCode(callSuper=false),这时候生成的 equals()办法只会比拟子类的属性,不会思考从父类继承的属性,无论父类属性拜访权限是否凋谢。
  2. 应用 @Builder 时要加上 @AllArgsConstructor,否则可能会报错。

5. 不便于调试

咱们平时大部分人都喜爱用 debug 调试定位问题,然而应用 lombok 生成的代码不太好调试。

6. 上下游零碎强依赖

如果上游零碎中提供的 fegin client 应用了 lombok,那么上游零碎必须也应用 lombok,否则会报错,上下游零碎形成了强依赖。

咱们该如何抉择?

lombok 有利有弊,咱们该如何抉择呢?

集体倡议要联合我的项目的理论状况做最正当的抉择。

  1. 如果你参加的是一个新我的项目,上下游零碎都是新的,这时候倡议应用 lombok,因为它能够显著晋升开发效率。
  2. 如果你参加的是一个老我的项目,并且以前没有应用过 lombok,倡议你前面也不要应用,因为代码革新老本较高。如果以前应用过 lombok,倡议你前面也应用,因为代码革新老本较高。
  3. 其实只有引入 jar 包可能都有:强制要求队友装置 idea 插件、降级 JDK 对性能有影响、有一些坑 和 上下游零碎强依赖 这几个问题,只有制订好标准,多总结应用教训这些问题不大。
  4. 代码的可读性变差 和 不便于调试 这两个问题,我认为也不大,因为 lombok 个别被应用在 javabean 上,该类的逻辑相对来说比较简单,很多代码一眼就能看明确,即便不调试问题起因也能猜想 7、8 分。

最初说一句(求关注,别白嫖我)

如果这篇文章对您有所帮忙,或者有所启发的话,帮忙扫描下发二维码关注一下,您的反对是我保持写作最大的能源。

求一键三连:点赞、转发、在看。

本文由博客群发一文多发等经营工具平台 OpenWrite 公布

退出移动版