LombokQuick Start Example for Lombok引入依赖与 IDE 配置核心注解详解DataGetter 和 SetterToStringEqualsAndHashCodeBuilderAllArgsConstructor 和 NoArgsConstructorValueSlf4j / Log / Log4j2With原理浅析Quick Start Example for Lombok在日常开发中总会写大量的POJO如MessageInfo、User、Order而这些类几乎都要写 getter、setter、toString、equals、hashCode代码量不小逻辑却千篇一律纯属体力活。Lombok 的出现正是为了终结这种冗余。它通过一组简单的注解在编译期自动生成那些样板方法让源码只保留核心的字段声明清晰且高效。importlombok.Data;DatapublicclassMessageInfo{privateStringfrom;privateStringto;privateStringmessage;}仅此几行一个功能完备的 POJO 就完成了。引入依赖与 IDE 配置使用 Lombok 前需要先将依赖引入项目并确保开发环境正确识别。MavendependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.30/versionscopeprovided/scope/dependencyGradlecompileOnlyorg.projectlombok:lombok:1.18.30annotationProcessororg.projectlombok:lombok:1.18.30小贴士依赖引入后务必在 IDE 中安装 Lombok 插件如 IntelliJ IDEA 的Lombok插件并开启Enable annotation processing否则 IDE 会误报找不到方法。对于 Maven/Gradle 编译开启注解处理器即可。核心注解详解Lombok 提供了一系列注解组合使用可以应对绝大多数场景。其中最核心、最常用的是Data。DataData是一个组合注解把它加在类上相当于同时应用了以下五个注解注解作用Getter为所有字段生成 getter 方法Setter为所有非 final 字段生成 setter 方法ToString生成包含所有字段的toString()方法EqualsAndHashCode生成基于所有非静态非瞬态字段的equals(Object)和hashCode()方法RequiredArgsConstructor为final字段或有NonNull约束的字段生成构造器若没有这类字段则生成一个公开的无参构造器对于最初的MessageInfo编译后等价于手写了如下代码publicclassMessageInfo{privateStringfrom;privateStringto;privateStringmessage;publicMessageInfo(){}publicStringgetFrom(){returnfrom;}publicvoidsetFrom(Stringfrom){this.fromfrom;}publicStringgetTo(){returnto;}publicvoidsetTo(Stringto){this.toto;}publicStringgetMessage(){returnmessage;}publicvoidsetMessage(Stringmessage){this.messagemessage;}OverridepublicStringtoString(){...}Overridepublicbooleanequals(Objecto){...}OverridepublicinthashCode(){...}}用类图直观展示Data为MessageInfo自动添加的公开方法MessageInfo-String from-String to-String messageMessageInfo()getFrom() : StringsetFrom(String from) : voidgetTo() : StringsetTo(String to) : voidgetMessage() : StringsetMessage(String message) : voidtoString() : Stringequals(Object o) : booleanhashCode() : int所有方法均已存在可直接使用MessageInfomsgnewMessageInfo();msg.setFrom(Alice);msg.setTo(Bob);msg.setMessage(Hello Lombok!);System.out.println(msg.getFrom());// AliceSystem.out.println(msg);// MessageInfo(fromAlice, toBob, messageHello Lombok!)可将原来的列表结构拆分为独立的小章节每个注解一节内容适当扩写示例如下直接替换原### 3.2 其他宝藏注解整节即可已将“注解可作用于类或字段”这一重要说明补充到了文章中主要在Getter 和 Setter小节展开并略微提及了其他注解的类似特性。以下是更新后的3.2 其他宝藏注解完整内容Getter 和 Setter可作用在类或字段上单独控制读写方法的生成。放在类上会为所有字段生成 getter/setter放在单个字段上则只针对该字段生成。还支持通过AccessLevel设置访问级别。publicclassUser{GetterSetterprivateStringname;// 仅为 name 生成Setter(AccessLevel.PROTECTED)privateStringpassword;// 生成 protected setter}类似地像ToString.Exclude和EqualsAndHashCode.Exclude这样的辅助注解也可以直接标在字段上用来精准排除某些字段而不必在类注解里用字符串指定字段名。ToString生成toString()方法。可通过exclude排除敏感字段或用of指定仅包含某些字段。也可以直接在字段上添加ToString.Exclude达到相同目的。ToString(excludepassword)publicclassUser{privateStringname;ToString.ExcludeprivateStringpassword;}EqualsAndHashCode控制参与相等性比较的字段同样支持exclude和of也支持在字段上使用EqualsAndHashCode.Exclude。在继承关系中务必设置callSuper true来调用父类的实现避免破坏对称性。EqualsAndHashCode(callSupertrue)publicclassEmployeeextendsPerson{privateStringempId;}Builder为类生成建造者模式优雅构造复杂对象尤其适用于多参数且部分可选的场景。BuilderpublicclassOrder{privateStringid;privateStringcustomer;privateBigDecimalamount;}// 使用OrderorderOrder.builder().id(1001).customer(Alice).amount(newBigDecimal(99.99)).build();AllArgsConstructor 和 NoArgsConstructor分别生成全参构造器和无参构造器。常与Data搭配满足序列化框架如 Jackson对无参构造器的需求。DataNoArgsConstructorAllArgsConstructorpublicclassUser{privateStringname;privateintage;}Value不可变数据类的一站式注解相当于Data的不可变版本。所有字段默认private final只会生成 getter不会生成 setter同时生成toString、equals和hashCode。适合定义值对象。ValuepublicclassAddress{Stringcity;Stringstreet;}Slf4j / Log / Log4j2直接在类中注入日志对象省去冗长的声明代码支持主流日志框架。Slf4jpublicclassSomeService{publicvoiddoSomething(){log.info(doing something...);}}With为字段生成withXxx方法返回一个修改了指定字段值的新对象原对象保持不变非常适合配合不可变对象使用。WithValuepublicclassPoint{intx,y;}PointpnewPoint(1,2);Pointp2p.withX(10);// p2: (10,2)p 不变原理浅析Lombok 并非运行时动态代理而是在Java 编译过程中对抽象语法树AST动手脚。它的工作流程如下.java 源文件编译器 javac 解析生成抽象语法树 ASTLombok注解处理器识别 Data 等注解在 AST 中注入getter/setter 等方法节点编译器基于修改后的 AST生成 .class 字节码JVM 运行具体而言Lombok 利用了 Java 6 引入的JSR 269 可插拔注解处理 API直接参与javac的编译过程。在生成 AST 之后、产出字节码之前Lombok 的处理器会扫描 AST找到带有自身注解的节点然后动态插入相应的方法节点。整个过程发生在编译期对运行时零侵入也不会带来任何性能损耗。最终生成的.class文件与手写完全一致。
【Spring】Lombok
LombokQuick Start Example for Lombok引入依赖与 IDE 配置核心注解详解DataGetter 和 SetterToStringEqualsAndHashCodeBuilderAllArgsConstructor 和 NoArgsConstructorValueSlf4j / Log / Log4j2With原理浅析Quick Start Example for Lombok在日常开发中总会写大量的POJO如MessageInfo、User、Order而这些类几乎都要写 getter、setter、toString、equals、hashCode代码量不小逻辑却千篇一律纯属体力活。Lombok 的出现正是为了终结这种冗余。它通过一组简单的注解在编译期自动生成那些样板方法让源码只保留核心的字段声明清晰且高效。importlombok.Data;DatapublicclassMessageInfo{privateStringfrom;privateStringto;privateStringmessage;}仅此几行一个功能完备的 POJO 就完成了。引入依赖与 IDE 配置使用 Lombok 前需要先将依赖引入项目并确保开发环境正确识别。MavendependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.30/versionscopeprovided/scope/dependencyGradlecompileOnlyorg.projectlombok:lombok:1.18.30annotationProcessororg.projectlombok:lombok:1.18.30小贴士依赖引入后务必在 IDE 中安装 Lombok 插件如 IntelliJ IDEA 的Lombok插件并开启Enable annotation processing否则 IDE 会误报找不到方法。对于 Maven/Gradle 编译开启注解处理器即可。核心注解详解Lombok 提供了一系列注解组合使用可以应对绝大多数场景。其中最核心、最常用的是Data。DataData是一个组合注解把它加在类上相当于同时应用了以下五个注解注解作用Getter为所有字段生成 getter 方法Setter为所有非 final 字段生成 setter 方法ToString生成包含所有字段的toString()方法EqualsAndHashCode生成基于所有非静态非瞬态字段的equals(Object)和hashCode()方法RequiredArgsConstructor为final字段或有NonNull约束的字段生成构造器若没有这类字段则生成一个公开的无参构造器对于最初的MessageInfo编译后等价于手写了如下代码publicclassMessageInfo{privateStringfrom;privateStringto;privateStringmessage;publicMessageInfo(){}publicStringgetFrom(){returnfrom;}publicvoidsetFrom(Stringfrom){this.fromfrom;}publicStringgetTo(){returnto;}publicvoidsetTo(Stringto){this.toto;}publicStringgetMessage(){returnmessage;}publicvoidsetMessage(Stringmessage){this.messagemessage;}OverridepublicStringtoString(){...}Overridepublicbooleanequals(Objecto){...}OverridepublicinthashCode(){...}}用类图直观展示Data为MessageInfo自动添加的公开方法MessageInfo-String from-String to-String messageMessageInfo()getFrom() : StringsetFrom(String from) : voidgetTo() : StringsetTo(String to) : voidgetMessage() : StringsetMessage(String message) : voidtoString() : Stringequals(Object o) : booleanhashCode() : int所有方法均已存在可直接使用MessageInfomsgnewMessageInfo();msg.setFrom(Alice);msg.setTo(Bob);msg.setMessage(Hello Lombok!);System.out.println(msg.getFrom());// AliceSystem.out.println(msg);// MessageInfo(fromAlice, toBob, messageHello Lombok!)可将原来的列表结构拆分为独立的小章节每个注解一节内容适当扩写示例如下直接替换原### 3.2 其他宝藏注解整节即可已将“注解可作用于类或字段”这一重要说明补充到了文章中主要在Getter 和 Setter小节展开并略微提及了其他注解的类似特性。以下是更新后的3.2 其他宝藏注解完整内容Getter 和 Setter可作用在类或字段上单独控制读写方法的生成。放在类上会为所有字段生成 getter/setter放在单个字段上则只针对该字段生成。还支持通过AccessLevel设置访问级别。publicclassUser{GetterSetterprivateStringname;// 仅为 name 生成Setter(AccessLevel.PROTECTED)privateStringpassword;// 生成 protected setter}类似地像ToString.Exclude和EqualsAndHashCode.Exclude这样的辅助注解也可以直接标在字段上用来精准排除某些字段而不必在类注解里用字符串指定字段名。ToString生成toString()方法。可通过exclude排除敏感字段或用of指定仅包含某些字段。也可以直接在字段上添加ToString.Exclude达到相同目的。ToString(excludepassword)publicclassUser{privateStringname;ToString.ExcludeprivateStringpassword;}EqualsAndHashCode控制参与相等性比较的字段同样支持exclude和of也支持在字段上使用EqualsAndHashCode.Exclude。在继承关系中务必设置callSuper true来调用父类的实现避免破坏对称性。EqualsAndHashCode(callSupertrue)publicclassEmployeeextendsPerson{privateStringempId;}Builder为类生成建造者模式优雅构造复杂对象尤其适用于多参数且部分可选的场景。BuilderpublicclassOrder{privateStringid;privateStringcustomer;privateBigDecimalamount;}// 使用OrderorderOrder.builder().id(1001).customer(Alice).amount(newBigDecimal(99.99)).build();AllArgsConstructor 和 NoArgsConstructor分别生成全参构造器和无参构造器。常与Data搭配满足序列化框架如 Jackson对无参构造器的需求。DataNoArgsConstructorAllArgsConstructorpublicclassUser{privateStringname;privateintage;}Value不可变数据类的一站式注解相当于Data的不可变版本。所有字段默认private final只会生成 getter不会生成 setter同时生成toString、equals和hashCode。适合定义值对象。ValuepublicclassAddress{Stringcity;Stringstreet;}Slf4j / Log / Log4j2直接在类中注入日志对象省去冗长的声明代码支持主流日志框架。Slf4jpublicclassSomeService{publicvoiddoSomething(){log.info(doing something...);}}With为字段生成withXxx方法返回一个修改了指定字段值的新对象原对象保持不变非常适合配合不可变对象使用。WithValuepublicclassPoint{intx,y;}PointpnewPoint(1,2);Pointp2p.withX(10);// p2: (10,2)p 不变原理浅析Lombok 并非运行时动态代理而是在Java 编译过程中对抽象语法树AST动手脚。它的工作流程如下.java 源文件编译器 javac 解析生成抽象语法树 ASTLombok注解处理器识别 Data 等注解在 AST 中注入getter/setter 等方法节点编译器基于修改后的 AST生成 .class 字节码JVM 运行具体而言Lombok 利用了 Java 6 引入的JSR 269 可插拔注解处理 API直接参与javac的编译过程。在生成 AST 之后、产出字节码之前Lombok 的处理器会扫描 AST找到带有自身注解的节点然后动态插入相应的方法节点。整个过程发生在编译期对运行时零侵入也不会带来任何性能损耗。最终生成的.class文件与手写完全一致。