Lombok——让你的JavaBean变漂亮

目录

 

●什么是JavaBean

●什么是Lombok

●使用前的准备

●使用Lombok装点你的JavaBean

●Lombok的其他常用特性

●小结


●什么是JavaBean

对于JavaBean,最简单的理解就是一个具备下面三个条件的Java类:

1、拥有一个或多个private修饰的成员变量;

2、该类具有无参构造函数;

3、每个成员变量都有get和set方法。

通常在我们的代码或者说项目中,JavaBean的表现形式主要是各种DO、DTO等,例如:ORM的数据库表单对象、用于前后端传输的对象等。

 

●什么是Lombok

Lombok是一个第三方Java库,它的主要作用是通过注解的形式,减少代码中的一些固定/模板化的代码,例如set、get、equal等方法;同时,它还具备日志的相关特性。

Lombok遵守MIT开源协议,是一个商业友好的Java库。其Github地址和官方门户如下:

https://github.com/rzwitserloot/lombok

https://www.projectlombok.org/

最初想到使用Lombok是因为学习建造者(Builder)模式时,发现自己去写模板代码有点麻烦,网上找了找发现Lombok可以解决,遂研究了一番。

 

●使用前的准备

笔者使用IDEA,配合Maven项目为例,介绍下使用Lombok前需要做的两件事——

1、在IDE中添加Lombok插件,目的是消除语法告警:

首先在IDEA中搜索安装Lombok Plugin

如果无法在软件内在线安装,可以去IDEA插件网站http://plugins.jetbrains.com/下载对应版本的插件,从本地进行离线安装(Install plugin from disk)

重启下IDEA,插件安装成功生效

 

2、在项目中引入Lombok的jar包:

在maven官方仓或者阿里仓搜索Project Lombok,选择合适的版本,将依赖填入项目中的pom文件

 

●使用Lombok装点你的JavaBean

Lombok最简单的用法,是在JavaBean中取代set、get方法。只需要在类的成员变量中加上注解@Setter和@Getter就可以了。你以下三种写法都是可以的,笔者喜欢第二种,美观:

//写法1
@Getter
@Setter
private String plateNo;

//写法2
@Getter @Setter
private String laneName;

//写法3
@Getter @Setter private String driveway;

也许你会说,IDEA中右键点击几下也是可以自动生成set、get方法的。没错!但是,有个问题,如果你修改了成员变量的类型,你需要手动修改相应set、get方法的入参或返回值类型,或者删掉重新生成一次。而使用注解则不会有这个问题。这是使用Lombok注解@setter、@getter的好处之一

另外,使用注解的第二个好处也是显而易见的,能够减少代码量,直观地看出该成员变量是否拥有set、get方法。值得注意的是,如果该成员变量是boolean类型,对应的是is方法。即以变量var为例,注释后,可以使用setVar()、getVar()/isVar()方法。

Lombok注解@setter、@getter的第三个好处是可以自由的控制成员变量的访问范围,通常,我们使用IDEA自动生成的set、get方法都是public的,当然你可以自己一个一个手动去修改。如果成员变量多了,改起来就比较麻烦。而Lombok注解@setter、@getter可以结合AccessLevel关键字限制权限,包括PUBLIC, PROTECTED, PACKAGE(对应default,即不写的情况)以及 PRIVATE四种。用法如下:

//Lombok注解
@Setter(AccessLevel.PROTECTED) private String name;

//传统写法
private String name;

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

 

●Lombok的其他常用特性

Lombok如果只是提供@setter、@getter注解的话,那咱也没有必要特意选用它了。它还具备一些好用的注解。

回到前面说的,在学习建造者(Builder)模式的时候,笔者发现Lombok可以化繁为简。

我们先说说建造者模式,这是一种生成对象的设计模式,设计初衷是为了让使用者通过链式调用的方式产生对象,而不是写多行set方法设置属性:

//非建造者模式
People people = new People();
people.setName("小明");
people.setAge(15);
people.setHobby("写代码");
people.setTag("初级程序员");

//建造者模式
People people = People.builder().name("小明").age(15).hobby("写代码").tag("初级程序员").build();

我们先来用正统方式实现这个建造者模式:

public class People {

  private String name;
  private int age;
  private String hobby;
  private String tag;

  // 构造方法私有化,避免直接调用构造方法
  private People(String name, int age, String hobby, String tag) {
    this.name = name;
    this.age = age;
    this.hobby = hobby;
    this.tag = tag;
  }

  public static PeopleBuilder builder() {
    return new PeopleBuilder();
  }

  //内部类
  public static class PeopleBuilder {

    // 和 People 一样的成员变量
    private String name;
    private int age;
    private String hobby;
    private String tag;

    private PeopleBuilder() {
    }

    // 链式调用设置各个属性值,返回 this,即 PeopleBuilder
    public PeopleBuilder name(String name) {
      this.name = name;
      return this;
    }

    public PeopleBuilder hobby(String hobby) {
      this.hobby = hobby;
      return this;
    }

    public PeopleBuilder tag(String tag) {
      this.tag = tag;
      return this;
    }

    public PeopleBuilder age(int age) {
      this.age = age;
      return this;
    }

    // build() 方法负责将 PeopleBuilder 中设置好的属性“复制”到 People 中。
    // 也,可以在 “复制” 之前做点检验
    public People build() {
      if (name == null || tag == null) {
        throw new RuntimeException("姓名和标签不能为空");
      }
      if (age <= 0 || age >= 150) {
        throw new RuntimeException("年龄范围不正确");
      }

      return new People(name, age, hobby, tag);
    }
  }
}

虽然建造者模式使用起来很舒服,但是写起来其实是比较麻烦的,有很多固定套路的模板代码需要手动写。而Lombok提供了一个注解@Builder,就可以实现上述功能。只需要在类上加上这个注释,就可以直接链式调用,简直神器!

@Builder
public class People {
  private String name;
  private int age;
  private String hobby;
  private String tag;
}

//定义如上,用法如下
People people = People.builder().name("小明").age(15).hobby("写代码").tag("初级程序员").build();

最后,再给大家推荐下Lombok的日志注解。大家的项目中如果用到了日志,例如slf4j,那肯定经常看到这样的代码:

public class myServiceImpl implements myService {

  private final Logger log = LoggerFactory.getLogger(myServiceImpl.class);

  ………………
  log.error("error data format: " + String.valueOf(arg));
  ………………

}

每一个类都需要写一遍这样的模板代码,当然,笔者之前的文章《Hutool不糊涂(一)》种介绍了一种解决方法。现在我们使用Lombok提供的日志类注解,可以更精美的解决这个问题,只需要在类上加上@Slf4j即可:

@Slf4j
public class myServiceImpl implements myService {

  ………………
  //可以直接使用这个log对象了
  log.error("error data format: " + String.valueOf(arg));
  ………………

}

除了slf4j,Lombok也提供了其他常用的日志系统的注解,如下:

@CommonsLog
Creates private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);

@Flogger
Creates private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();

@JBossLog
Creates private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);

@Log
Creates private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

@Log4j
Creates private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);

@Log4j2
Creates private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

@Slf4j
Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

@XSlf4j
Creates private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

​​​​​​​

●小结

本文抛砖引玉,给大家介绍下Lombok最常用的三种注解,其实Lombok还有不少注解,例如@Synchronized、@ToString、@NonNull、@Cleanup以及@Data等。一方面,网上有不少文章介绍了这几个注解,另一方面,大家也可以结合自己的需要参考官方指南或者Javadoc

当然了,虽然Lombok开源协议商业友好,但是也并非没有缺点,对于学习者来说,使用多了注解,就和以前文字说的使用多了语法糖的后果一样,导致不会自己写设计模式了,需要在开发效率和自我提升上做一个权衡。今天,你学会了吗?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值