Lombok (自动生成get、set方法)介绍

Lombok使用

介绍

在项目中使用Lombok可以减少很多重复代码的书写。比如说getter/setter/toString等方法的编写。

IDEA中的安装

打开IDEA的Setting –> 选择Plugins选项 –> 选择Browse repositories –> 搜索lombok –> 点击安装 –> 安装完成重启IDEA –> 安装成功

idea安装Lombok

引入依赖

在项目中添加Lombok依赖jar,在pom文件中添加如下部分。(不清楚版本可以在Maven仓库中搜索)

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.18</version>
    <scope>provided</scope>
</dependency>

使用

在对应的类或者方法上使用对应注解即可。例如:
示例

Lombok有哪些注解

  • @Setter
  • @Getter
  • @Data
  • @Log(这是一个泛型注解,具体有很多种形式)
  • @AllArgsConstructor
  • @NoArgsConstructor
  • @EqualsAndHashCode
  • @NonNull
  • @Cleanup
  • @ToString
  • @RequiredArgsConstructor
  • @Value
  • @SneakyThrows
  • @Synchronized

注解详情

log

注解在  上。有如下可选择可用:

//@CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
//@JBossLog
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
//@Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
//@Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
//@Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
//@Slf4j
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
//@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

默认情况下,记录器的主题(或名称)将是使用注释进行@Log注释的类的类名称。这可以通过指定topic参数来定制。例如:@XSlf4j(topic="reporting")

该类型注解可以满足不同的日志系统的日志使用,Lombok提供了一些自定义配置项可以参看官方说明文档。

Log官方介绍

@Getter和@Setter

该注解使用在类或者属性上,该注解可以使用在类上也可以使用在属性上。生成的getter遵循布尔属性的约定。例如:boolean类型的sex,getter方法为isSex而不是getSex

在使用该注解时,会默认生成一个无参构造。和对应的getterhe setter方法
示例

该注解也可以使用在单个属性上,会默认生成一个无参构造:
示例

@Data

该注解使用在上,该注解会提供getter、setter、equals、canEqual、hashCode、toString方法。

示例

@NonNull

该注解使用在属性上,该注解用于属的非空检查,当放在setter方法的字段上,将生成一个空检查,如果为空,则抛出NullPointerException
该注解会默认是生成一个无参构造。
示例

@toString

该注解使用在上,该注解默认生成任何非讲台字段以名称-值的形式输出。
1、如果需要可以通过注释参数includeFieldNames来控制输出中是否包含的属性名称。
2、可以通过exclude参数中包含字段名称,可以从生成的方法中排除特定字段。
3、可以通过callSuper参数控制父类的输出。

  • includeFieldNames是否包含属性名称:
    示例
  • exclude 排除指定字段
    示例
  • callSuper输出父类属性
    示例

注意:父类也要有toString方法,不然打印的是对象内存地址

//父类无toString方法
Person(super=com.motui.Person@3abfe836, firstName=motui, address=北京, dateOfBirth=Tue Jan 09 11:49:05 CST 2018, sex=true)
//父类有toString方法
Person(super=People(id=111), firstName=motui, address=北京, dateOfBirth=Tue Jan 09 11:50:11 CST 2018, sex=true)

@EqualsAndHashCode

该注解使用在上,该注解在类级别注释会同时生成equalshashCode
注意继承关系的时候该注解的使用。详细介绍参照官方介绍
示例
存在继承关系需要设置callSuper参数为true

@Data

该注解使用在上,该注解是最常用的注解,它结合了@ToString,@EqualsAndHashCode, @Getter和@Setter。本质上使用@Data注解,类默认@ToString@EqualsAndHashCode以及每个字段都有@Setter@getter。该注解也会生成一个公共构造函数,可以将任何@NonNullfinal字段作为参数。

虽然@Data注解非常有用,但是它没有与其他注解相同的控制粒度。@Data提供了一个可以生成静态工厂的单一参数,将staticConstructor参数设置为所需要的名称,Lombok自动生成的构造函数设置为私有,并提供公开的给定名称的静态工厂方法。
示例

@AllArgsConstructor

该注解使用在上,该注解提供一个全参数的构造方法,默认不提供无参构造。
示例

@NoArgsConstructor

该注解使用在上,该注解提供一个无参构造
示例

@RequiredArgsConstructor

该注解使用在上,使用类中所有带有 @NonNull 注解的或者带有 final 修饰的成员变量生成对应的构造方法。
实例

@Value

这个注解用在 类 上,会生成含所有参数的构造方法,get 方法,此外还提供了equals、hashCode、toString 方法。
注意:没有setter
示例

@Cleanup

该注解使用在属性前,该注解是用来保证分配的资源被释放。在本地变量上使用该注解,任何后续代码都将封装在try/finally中,确保当前作用于中的资源被释放。默认@Cleanup清理的方法为close,可以使用value指定不同的方法名称。
示例

@Synchronized

该注解使用在类或者实例方法上,Synchronized在一个方法上,使用关键字可能会导致结果和想要的结果不同,因为多线程情况下会出现异常情况。Synchronized
关键字将在this示例方法情况下锁定当前对象,或者class讲台方法的对象上多锁定。这可能会导致死锁现象。一般情况下建议锁定一个专门用于此目的的独立锁,而不是允许公共对象进行锁定。该注解也是为了达到该目的。
示例

@SneakyThrows

该注解使用在方法上,这个注解用在 方法 上,可以将方法中的代码用 try-catch 语句包裹起来,捕获异常并在 catch 中用 Lombok.sneakyThrow(e) 把异常抛出,可以使用 @SneakyThrows(Exception.class) 的形式指定抛出哪种异常。该注解需要谨慎使用。详情参看官方介绍
示例

结语

Lombok的目的是减少代码的重复编写,并提供比较好的解决方案。当然也存在一些争议性的注解,可以根据实际场景进项使用。Lombok有一些实验注解可以在官网查看。

 

@Log (and friends)

Captain's Log, stardate 24435.7: "What was that line again?"

The various @Log variants were added in lombok v0.10. NEW in lombok 0.10: You can annotate any class with a log annotation to let lombok generate a logger field.
The logger is named log and the field's type depends on which logger you have selected.

NEW in lombok v1.16.24: Addition of google's FluentLogger (via @Flogger).

NEW in lombok v1.18.10: Addition of @CustomLog which lets you add any logger by configuring how to create them with a config key.

Overview

You put the variant of @Log on your class (whichever one applies to the logging system you use); you then have a static final log field, initialized as is the commonly prescribed way for the logging framework you use, which you can then use to write log statements.

There are several choices available:

@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);
@CustomLog
Creates private static final com.foo.your.Logger log = com.foo.your.LoggerFactory.createYourLogger(LogExample.class);

This option requires that you add a configuration to your lombok.config file to specify what @CustomLog should do.

For example:lombok.log.custom.declaration = com.foo.your.Logger com.foo.your.LoggerFactory.createYourLog(TYPE)(TOPIC) which would produce the above statement. First comes a type which is the type of your logger, then a space, then the type of your logger factory, then a dot, then the name of the logger factory method, and then 1 or 2 parameter definitions; at most one definition with TOPIC and at most one without TOPIC. Each parameter definition is specified as a parenthesised comma-separated list of parameter kinds. The options are: TYPE (passes this @Log decorated type, as a class), NAME (passes this @Log decorated type's fully qualified name), TOPIC (passes the explicitly chosen topic string set on the @CustomLog annotation), and NULL (passes null).

The logger type is optional; if it is omitted, the logger factory type is used. (So, if your logger class has a static method that creates loggers, you can shorten your logger definition).

Please contact us if there is a public, open source, somewhat commonly used logging framework that we don't yet have an explicit annotation for. The primary purpose of @CustomLog is to support your in-house, private logging frameworks.

 

By default, the topic (or name) of the logger will be the (name of) the class annotated with the @Log annotation. This can be customised by specifying the topic parameter. For example: @XSlf4j(topic="reporting").

With Lombok

import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;

@Log
public class LogExample {
  
  public static void main(String... args) {
    log.severe("Something's wrong here");
  }
}

@Slf4j
public class LogExampleOther {
  
  public static void main(String... args) {
    log.error("Something else is wrong here");
  }
}

@CommonsLog(topic="CounterLog")
public class LogExampleCategory {

  public static void main(String... args) {
    log.error("Calling the 'CounterLog' with a message");
  }
}
 

Vanilla Java

public class LogExample {
  private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
  
  public static void main(String... args) {
    log.severe("Something's wrong here");
  }
}

public class LogExampleOther {
  private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);
  
  public static void main(String... args) {
    log.error("Something else is wrong here");
  }
}

public class LogExampleCategory {
  private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");

  public static void main(String... args) {
    log.error("Calling the 'CounterLog' with a message");
  }
}

Supported configuration keys:

lombok.log.fieldName = an identifier (default: log).
The generated logger fieldname is by default 'log', but you can change it to a different name with this setting.
lombok.log.fieldIsStatic = [true | false] (default: true)
Normally the generated logger is a static field. By setting this key to false, the generated field will be an instance field instead.
lombok.log.custom.declaration = LoggerType LoggerFactoryType.loggerFactoryMethod(loggerFactoryMethodParams)(loggerFactoryMethodParams)
Configures what to generate when @CustomLog is used. (The italicized parts are optional). loggerFactoryMethodParams is a comma-separated list of zero to any number of parameter kinds to pass. Valid kinds: TYPE, NAME, TOPIC, and NULL. You can include a parameter definition for the case where no explicit topic is set (do not include the TOPIC in the parameter list), and for when an explicit topic is set (do include the TOPIC parameter in the list).
lombok.log.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of any of the various log annotations as a warning or error if configured.
lombok.log.custom.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.CustomLog as a warning or error if configured.
lombok.log.apacheCommons.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.apachecommons.CommonsLog as a warning or error if configured.
lombok.log.flogger.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.flogger.Flogger as a warning or error if configured.
lombok.log.jbosslog.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.jbosslog.JBossLog as a warning or error if configured.
lombok.log.javaUtilLogging.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.java.Log as a warning or error if configured.
lombok.log.log4j.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.log4j.Log4j as a warning or error if configured.
lombok.log.log4j2.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.log4j.Log4j2 as a warning or error if configured.
lombok.log.slf4j.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.slf4j.Slf4j as a warning or error if configured.
lombok.log.xslf4j.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.slf4j.XSlf4j as a warning or error if configured.

Small print

If a field called log already exists, a warning will be emitted and no code will be generated.

A future feature of lombok's diverse log annotations is to find calls to the logger field and, if the chosen logging framework supports it and the log level can be compile-time determined from the log call, guard it with an if statement. This way if the log statement ends up being ignored, the potentially expensive calculation of the log string is avoided entirely. This does mean that you should NOT put any side-effects in the expression that you log.

Lombok 介绍及使用

在这里插入图片描述


一,Lombok介绍

在 Java 开发中,常常需要编写大量的getter、setter方法、equals和hashCode方法、构造函数等重复且繁琐的代码。

为了减少 Java 代码中的冗余和样板代码,提高代码的可读性和开发效率,就有了Lombok的出现。

Lombok是一个 Java 库,它通过使用注解来简化 Java 代码的编写。它提供了一系列的注解,用于自动生成常见的代码,如gettersetter方法、构造函数equalshashCode方法等,以减少开发者的重复劳动。

使用Lombok,开发者只需在 Java 类上添加相应的注解,而不需要手动编写相应的代码。在编译过程中,Lombok会根据这些注解自动生成对应的代码,减少代码中的冗余和样板代码以及简化代码的编写过程。

使用Lombok可以提高代码的可读性、简洁性和可维护性,让开发者能够更专注于业务逻辑的实现。


二,Lombok下载

要想使用Lombok,需要在项目的构建工具中引入Lombok的依赖,并在开发环境中安装对应的插件,以支持Lombok的注解和自动生成的代码的显示和编辑。

1,Lombok插件安装

按照图中标记依次操作就可以进行Lombok插件的安装,安装好后点击启动,重新打开IDEA即可。

image-20230716110805293

2,Lombok依赖引入

Lombok插件安装好后,就可以在项目的pom.xml文件中添加Lombok依赖,Lombok依赖信息如下:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

完成Lombok插件安装和Lombok依赖引入操作后,就可以使用Lombok了。


三,Lombok原理

Lombok基本实现原理

Lombok的基本实现原理可以概括为以下几个步骤:

  1. 注解扫描:Lombok的注解处理器会扫描Java源代码中的注解,并找到使用了Lombok注解的类、字段和方法。
  2. AST操作:Lombok注解处理器会对注解所标注的类进行抽象语法树(AST)的解析和操作,以识别和处理这些注解。
  3. 注解解析:注解处理器解析找到的注解,确定需要生成的代码类型和内容。
  4. 代码生成:基于注解的定义和规则,Lombok注解处理器生成相应的代码片段,如getter和setter方法、构造函数等。
  5. 代码注入:生成的代码片段被插入到编译结果中的相应位置,与手动编写的代码合并在一起。
  6. 最终编译:编译器将生成的代码和手动编写的代码一起编译为最终的字节码文件。

总结归纳:Lombok利用 Java 编译器的注解处理器技术,在编译期间扫描和解析使用了Lombok注解的源代码,然后会对注解所标注的类进行抽象语法树(AST)的解析和操作,以识别和处理这些注解。然后再根据注解的定义和规则,生成相应的代码片段,并将其插入到编译器的内部结构中。最后,生成的代码片段与手动编写的代码一起经过编译,生成可执行的字节码文件。


普通程序运行原理流程:

Lombok运行原理流程:


四,Lombok使用

常见的Lombok基本注解

注解 注解作用
@Getter 自动生成字段的getter方法
@Setter 自动生成字段的setter方法
@ToString 自动生成toString方法
@EqualsAndHashCode 自动生成equals和hashCode方法
@NoArgsConstructor 自动生成无参构造函数
@AllArgsConstructor 自动生成包含所有字段的构造函数

常见的Lombok组合注解

注解 注解作用
@Data 组合了@Getter、@Setter、@ToString、@EqualsAndHashCode等注解的功能
@Value 组合了@Getter、@ToString、@EqualsAndHashCode等注解的功能

思考:@Data注解和@Value注解有哪些区别?

解答:@Data生成的类是可变的,具有可读写的setter方法,@Value生成的类是不可变的,字段是final的,没有生成setter方法。

Lombok日志注解

注解 注解作用
@Slf4j 自动生成一个名为log的日志记录器

Lombok其他注解

注解 注解作用
@Builder 自动生成Builder模式的构造器方法
@NonNull 自动生成非空检查
@Delegate 自动生成委托方法
@Cleanup 自动释放资源

日志注解的使用

在上篇博客讲解日志打印的方式时,不难发现每次都使用LoggerFactoy.getLogger(lxxx.class)方法获取到 log对象的过程比较繁琐,而且要确保每个类对应的包都导入成功,那有什么方法来解决这个问题吗?

答案肯定是有的,使用Lombok中的日志注解@SIf4j就可以很好地解决上述操作过程的繁琐问题。

在添加 lombok 框架依赖后,使用 @Slf4j 注解就可在程序中使用log对象输入日志内容,并且只能使用 log 对象才能输出。

那为啥只能使用 log 对象才能输出呢? 这是因为log对象是lombok提供的对象。

使用Lombok的日志注解,并经过Lombok的一系列处理操作后,@Slf4J 注解会自动转换成对应的log对象创建代码。

与之对应的.java文件和编译生成的.class文件对比图:

image-20230716122057184

 

 

posted @ 2024-03-26 10:21  CharyGao  阅读(489)  评论(0)    收藏  举报