Spring Boot 2.x With lombok
1.什么是lombok?
官网地址:Project Lombok
1.1 官方解释
- 原文
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方法,使用一个注解,您的类具有一个功能齐全的构建器,自动化您的日志记录变量等等。
1.2 我的理解
lombok 是一个可以让你通过注解自动生成代码的类库
这是什么意思呢?
- 使用
@Getter
,@Setter
,@ToString
注解可以让我们省略编写Getter Setter ToString()方法- 使用
@Slf4j
注解省略Logger 日志的创建- 使用注解生成建造者模式的构造方法
常用注解对照表如下:
注解 | 自动生成代码 |
---|---|
@Getter |
public String getName() { return this.name; } |
@Setter |
public void setName(String name) { this.name = name; } |
@ToString |
public void setName(String name) { this.name = name; } |
@Slf4j |
private static final Logger log = LoggerFactory.getLogger(UserInfoController.class); |
2. 如何使用lombok?
2.1 安装lombok插件
由于该插件是在编译期间帮你自动生成的代码,因此为了让你的IDEA识别并兼容lombok,需要安装lombok插件。
2.1.1 Eclipse/ Spring Tools Suite (STS) 安装插件
Eclipse 版本推荐使用 Spring Tools Suite (STS),它是Spring 官方团队推出的Eclipse衍生版本,对Spring 有着极好的支持。
-
1.打开 Lombok 下载页面
-
2.点击Download 1.18.10, 会下载lombok.jar
-
3.双击运行或者通过java -jar lombok.jar方式运行
然后我们可以检查eclipse安装是否在eclipse关于对话框启用了lombok。 lombok版本将列在版权文本的末尾:
2.1.2 Intellij Idea 安装插件
要想让我们的Intellij Idea 支持并兼容
lombok
,需要添加lombok plugin
插件
安装方法如下:
- Go to File > Settings > Plugins
- Click on Browse repositories…
- Search for
Lombok Plugin
- Click on Install plugin
- Restart IntelliJ IDEA
2.2 添加lombok依赖
2.2.1 普通项目集成lombok
pom.xml添加依赖如下:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
2.2.2 Spring Boot 项目集成lombok
pom.xml添加依赖如下:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2.3 项目中使用Lombok
我们通过 https://start.spring.io/ 创建一个Spring Boot 项目
为了测试代码,我这里添加了Web依赖。
2.3.1 @Slf4j
编译前
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 功能
* @author 星云
* @date 2019/9/12 11:22
*/
@Slf4j
@RestController
public class LogController {
@GetMapping(value = "/log.do")
public String logMethod(){
log.trace("this is trace level message");
log.debug("this is debug level message");
log.info("this is info level message");
log.warn("this is warn level message");
log.error("this is error level message");
return "log test API";
}
}
编译后
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
private static final Logger log = LoggerFactory.getLogger(LogController.class);
public LogController() {
}
@GetMapping({"/log.do"})
public String logMethod() {
log.trace("this is trace level message");
log.debug("this is debug level message");
log.info("this is info level message");
log.warn("this is warn level message");
log.error("this is error level message");
return "log test API";
}
}
2.3.2 @Getter,@Setter@ToString
假设我们有一个POJO类 UserInfo.java,代码如下
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 功能
* @author 星云
* @date 2019/9/12 10:04
*/
@Getter
@Setter
@ToString
public class UserInfo {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
编译成class 后就会变成这样
public class UserInfo {
private String name;
private Integer age;
public UserInfo() {
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "UserInfo(name=" + this.getName() + ", age=" + this.getAge() + ")";
}
}
注意:
private String name
不能写成private static String name;
否则生成Getter 和Setter 以及ToString()会失败。
2.3.3 @AllArgsConstructor (慎用)
使用@AllArgsConstructor
注解可以自动生成带参数的构造方法。
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 功能
* @author 星云
* @date 2019/9/12 10:04
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
public class UserInfo {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
编译成class 后就会变成这样
public class UserInfo {
private String name;
private Integer age;
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "UserInfo(name=" + this.getName() + ", age=" + this.getAge() + ")";
}
public UserInfo(String name, Integer age) {
this.name = name;
this.age = age;
}
}
注意:
这个注解一定要慎用,如果用了需要自己写一个空的构造方法。
2.3.4 @Data
通过@Data 注解可以自动为字段的所有成员属性生成Getter,Setter,ToString() ,默认空的构造方法,重写equals 和hashcode 方法
import lombok.Data;
/**
* 功能
* @author 星云
* @date 2019/9/12 10:04
*/
@Data
public class UserInfo {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
编译成class 后就会变成这样
public class UserInfo {
private String name;
private Integer age;
public UserInfo() {
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof UserInfo)) {
return false;
} else {
UserInfo other = (UserInfo)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
Object this$age = this.getAge();
Object other$age = other.getAge();
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof UserInfo;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $name = this.getName();
int result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $age = this.getAge();
result = result * 59 + ($age == null ? 43 : $age.hashCode());
return result;
}
public String toString() {
return "UserInfo(name=" + this.getName() + ", age=" + this.getAge() + ")";
}
}
2.3.5 @Builder
@Builder 注解可以帮忙生成一个拥有建造者模式的构造方法。
什么意思呢?我们应该在某些开源类库中见过这种写法
import com.xingyun.springbootwithlomboksample.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 功能
*
* @author 星云
* @date 2019/9/12 9:50
*/
@Slf4j
@RestController
public class UserInfoController {
@GetMapping(value = "/userInfo")
public UserInfo listUserInfo(){
UserInfo userInfo=UserInfo.builder().name("星云").age(27).build();
return userInfo;
}
}
使用这种方式,大大简化了建造者模式的编写,第三方调用者也很清楚每个参数是什么意思,不需要特别解释。
POJO类编译前编写如下:
import lombok.Builder;
/**
* 功能
* @author 星云
* @date 2019/9/12 10:04
*/
@Builder
public class UserInfo {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
编译成class 后就会变成这样
public class UserInfo {
private String name;
private Integer age;
UserInfo(String name, Integer age) {
this.name = name;
this.age = age;
}
public static UserInfo.UserInfoBuilder builder() {
return new UserInfo.UserInfoBuilder();
}
public static class UserInfoBuilder {
private String name;
private Integer age;
UserInfoBuilder() {
}
public UserInfo.UserInfoBuilder name(String name) {
this.name = name;
return this;
}
public UserInfo.UserInfoBuilder age(Integer age) {
this.age = age;
return this;
}
public UserInfo build() {
return new UserInfo(this.name, this.age);
}
public String toString() {
return "UserInfo.UserInfoBuilder(name=" + this.name + ", age=" + this.age + ")";
}
}
}
本篇完~