Lombok Spring Boot And Lombok Annotations Lombok Java java Spring Boot by devs5003 - September 16, 2023June 2, 202417 Last Updated on June 2nd, 2024While developing a project in Java, we tend to repeat the similar kind of code for each class we create. Such kind of repetitive code is generally called boilerplate code. Our next question might be like ‘Can we get rid of such multiple lines of code in real time development?’ Then answer of your question is simply ‘Yes’. The next question should be ‘How can we reduce such kind of boilerplate code?’ Now the answer is ‘with the help of Lombok API, some people call it Lombok Project’. However, as the title “Lombok Spring Boot and Lombok Annotations” suggests, our focus in this article will be on the Lombok API Annotations. Furthermore, the ‘Lombok API’ is highly being used in the software industry to save lots of time & effort. Hence, it becomes more important to learn all about Lombok like What is Lombok?, how to use it?, where to use it?, what are the limitations on using it? etc. in detail. Now let’s get into our topic “Lombok Spring Boot and Lombok Annotations”. Table of Contents Toggle What is Lombok API or Lombok Project ?What are the benefits of using Lombok ?Where can we use Lombok API/Lombok Annotations?How to configure Lombok in eclipse/STS?Lombok Spring Boot and Lombok Annotations@Getter@SetterOptional parameter on @Getter and @Setter@ToString@EqualsAndHashCode@NonNull@RequiredArgsConstructor@Data@NoArgsConstructor@AllArgsConstructor@Cleanup@Builder@Synchronized@SneakyThrowsLogging Annotations@CommonsLog, @Slf4j, @Log4j, @Log4j2, @Flogger, @Log, @XSlf4j, @JBossLogFAQCan we use Lombok API in our real time project ?Can we customize Lombok-generated methods?Does Lombok have any impact on code quality or maintainability?Can I use Lombok with Java versions older than Java 8?Conclusion What is Lombok API or Lombok Project ? People in the industry use word Lombok Project, Lombok API, Lombok Library interchangeably. Of course, it is an open source Java API which automates the creation of boilerplate code like getter(), setter(), equals(), hashCode(), toString(), constructors etc… and reduces the time spent in writing such kind of codes just by adding annotations to your classes & its members. For example, suppose you have a class and you don’t want to implement its toString() method manually in your class. Then all you have to do is : add the @ToString at the top of your class. Simultaneously, the Lombok Project will use the fields of your class to implement the toString() method behind the scenes. Now, what will happen behind the scene? The implementation of toString() method will exist in compiled (.class) file but you can’t see it in your source (.java) file. Furthermore, Lombok modifies the source code before sending it to the compiler behind the scene. What are the benefits of using Lombok ? You might think that if we can generate code automatically with the help of an IDE (like Eclipse/STS etc.), then what will be the benefit of using Lombok? For example, suppose you have a POJO class containing 10 fields/properties. In the middle of development if you want to change number of fields, or name of field or datatype of field. Then you must either update the implementation of getterXXX(), setterXXX(), toString(), equals(), hashCode(), parameterized constructors etc. or remove them & regenerate once again. But if you use Lombok library, you don’t need to make any changes in mentioned methods or parameterized constructors. Lombok will take care of it and automatically update the changes in .class file. Moreover, if you remove any field from the class, Lombok will remove the same from .class file. In summary, you have to just declare the fields in your class and apply the annotations accordingly. Where can we use Lombok API/Lombok Annotations? Project Lombok can be configured in the following IDEs: Eclipse MyEclipse Spring Tool Suite (STS) IntelliJ IDEA Netbeans JBoss Developer Studio Visual Studio Code How to configure Lombok in eclipse/STS? We will configure Lombok in IDE(STS/Eclipse) so that we can take benefit of the annotations provided by it in our java classes. Step#1: Download the Lombok.jar from projectlombok.org If you are working on Maven project, provide the dependency of ‘Lombok’ in pom.xml and find the Lombok jar from location: ‘C:\Users\<username>\.m2\repository\org\projectlombok\lombok\1.18.12’ In case of STS, you can add Lombok as a starter project (want to know steps? click here). Step#2: Double click on the jar, you will see below screen with red chilli symbol. Step#3: It will automatically find the locations of installation of STS/Eclipse. If not, click on the ‘specify location’ and provide the path of your            STS/Eclipse installation Step#4: Make sure the checkbox is clicked, then click on install/update Step#5: Don’t forget to restart your STS/Eclipse Lombok Spring Boot and Lombok Annotations Note : All explained parameters with Annotations are optional, just for knowledge purpose. In fact, we can use every annotation without specifying any parameter. @Getter @Getter creates getter methods for members of a class. However, it can be used at class level & field level. Also, if applied at the class level, will generate getter methods for all fields. But if applied at field level, will generate getter of the same field only. For boolean fields it adds ‘is’ prefix in place of ‘get’. Further, below snapshot is self explanatory. @Setter @Setter creates setter methods for members of a class. However, it can be used at class level & field level. Also, if applied at the class level, will generate setter methods for all fields. But if applied at field level, will generate setter of the same field only. Optional parameter on @Getter and @Setter @Getter and @Setter can take optional parameter to declare access level for generated method like below. In that case code will be generated on the basis of the annotated access level. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.AccessLevel;import lombok.Getter;import lombok.Setter;@Getterpublic class Book { private String id; private String title; @Getter(AccessLevel.PRIVATE) double price; @Setter(AccessLevel.PROTECTED) private String author; @Setter(AccessLevel.PUBLIC) private boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;public class Book{ private String id; private String title; double price; private String author; private boolean available; private double getPrice() { return this.price; } protected void setAuthor(final String author) { this.author = author; } public void setAvailable(final boolean available) { this.available = available; } public String getId() { return this.id; } public String getTitle() { return this.title; } public String getAuthor() { return this.author; } public boolean isAvailable() { return this.available; }} @ToString @ToString creates an implementation of toString() method. By default It will not include any static field in the implementation of toString(). Further, we can exclude the specific field in the implemntation of toString() by using optional parameter ‘exclude’. We can also include the output of the toString() method of super class by setting optional parameter ‘callSuper’ to true. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.ToString;@ToString(callSuper=true,exclude="author")public class Book { private static String id; private String title; private double price; private String author; private boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;public class Book{ private static String id; private String title; private double price; private String author; private boolean available; @Override public String toString() { return "Book(super=" + super.toString() + ", title=" + this.title + ", price=" + this.price + ", available=" + this.available + ")"; }} @EqualsAndHashCode This annotation creates both equals() and hashCode() methods as both are tied together by the hashCode contract. By default both methods will include all fields except which are static and transient. Like @ToString ‘exclude’ parameter prevents a field from being included in the implemented methods. Also like @ToString we can optionally include ‘callSuper’ parameter. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.EqualsAndHashCode;@EqualsAndHashCode(exclude={"id"})public class Book { private String id; private String title; private Double price; private String author; private Boolean available; private static String publisher; private transient String ssn;} Converted Book.java package com.dev.springboot.lombok.entity;public class Book{ private String id; private String title; private Double price; private String author; private Boolean available; private static String publisher; private transient String ssn; @Override public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof Book)) { return false; } final Book other = (Book)o; if (!other.canEqual(this)) { return false; } final Object this$title = this.title; final Object other$title = other.title; Label_0065: { if (this$title == null) { if (other$title == null) { break Label_0065; } } else if (this$title.equals(other$title)) { break Label_0065; } return false; } final Object this$price = this.price; final Object other$price = other.price; Label_0102: { if (this$price == null) { if (other$price == null) { break Label_0102; } } else if (this$price.equals(other$price)) { break Label_0102; } return false; } final Object this$author = this.author; final Object other$author = other.author; Label_0139: { if (this$author == null) { if (other$author == null) { break Label_0139; } } else if (this$author.equals(other$author)) { break Label_0139; } return false; } final Object this$available = this.available; final Object other$available = other.available; if (this$available == null) { if (other$available == null) { return true; } } else if (this$available.equals(other$available)) { return true; } return false; } protected boolean canEqual(final Object other) { return other instanceof Book; } @Override public int hashCode() { final int PRIME = 59; int result = 1; final Object $title = this.title; result = result * 59 + (($title == null) ? 43 : $title.hashCode()); final Object $price = this.price; result = result * 59 + (($price == null) ? 43 : $price.hashCode()); final Object $author = this.author; result = result * 59 + (($author == null) ? 43 : $author.hashCode()); final Object $available = this.available; result = result * 59 + (($available == null) ? 43 : $available.hashCode()); return result; }} @NonNull When the @NonNull annotation is placed before a method parameter, or constructor parameter, it means that this method will not accept null as an argument. If you pass to it a null object, the method will automatically raise a NullPointerException. In fact, by using this annotation, you avoid having to manually check and to manually raise NullPointerException. Generally, this annotation is used by @RequiredArgsConstructor to indicate that variable is selected for parameterized constructor creation. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.NonNull;import lombok.Setter;@Setterpublic class Book { private String id; @NonNull private String title; @NonNull private Double price; @NonNull private String author; private Boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;import lombok.NonNull;public class Book{ private String id; @NonNull private String title; @NonNull private Double price; @NonNull private String author; private Boolean available; public void setId(final String id) { this.id = id; } public void setTitle(@NonNull final String title) { if (title == null) { throw new NullPointerException("title is marked non-null but is null"); } this.title = title; } public void setPrice(@NonNull final Double price) { if (price == null) { throw new NullPointerException("price is marked non-null but is null"); } this.price = price; } public void setAuthor(@NonNull final String author) { if (author == null) { throw new NullPointerException("author is marked non-null but is null"); } this.author = author; } public void setAvailable(final Boolean available) { this.available = available; }} @RequiredArgsConstructor We use this annotation to provide selected fields as parameters inside constructor, ie Parameterized constructor. Also Field should be selected using @NonNull annotation. Furthermore, if no field has this annotation, then zero field selected and it generates the default constructor only. This will also include fields in the constructor creation which are declared final. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.NonNull;import lombok.RequiredArgsConstructor;@RequiredArgsConstructorpublic class Book { private String id; @NonNull private String title; @NonNull private Double price; private final String author; private Boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;import lombok.NonNull;public class Book{ private String id; @NonNull private String title; @NonNull private Double price; private final String author; private Boolean available; public Book(@NonNull final String title, @NonNull final Double price, final String author) { if (title == null) { throw new NullPointerException("title is marked non-null but is null"); } if (price == null) { throw new NullPointerException("price is marked non-null but is null"); } this.title = title; this.price = price; this.author = author; }} @Data This annotation is a combination of the @ToString, @EqualsAndHashCode, @Getter, @Setter and @RequiredArgsConstructor annotations. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.Data;import lombok.NonNull;@Datapublic class Book { private String id; @NonNull private String title; @NonNull private Double price; private String author; private Boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;import lombok.NonNull;public class Book{ private String id; @NonNull private String title; @NonNull private Double price; private String author; private Boolean available; public String getId() { return this.id; } @NonNull public String getTitle() { return this.title; } @NonNull public Double getPrice() { return this.price; } public String getAuthor() { return this.author; } public Boolean getAvailable() { return this.available; } public void setId(final String id) { this.id = id; } public void setTitle(@NonNull final String title) { if (title == null) { throw new NullPointerException("title is marked non-null but is null"); } this.title = title; } public void setPrice(@NonNull final Double price) { if (price == null) { throw new NullPointerException("price is marked non-null but is null"); } this.price = price; } public void setAuthor(final String author) { this.author = author; } public void setAvailable(final Boolean available) { this.available = available; } @Override public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof Book)) { return false; } final Book other = (Book)o; if (!other.canEqual(this)) { return false; } final Object this$id = this.getId(); final Object other$id = other.getId(); Label_0065: { if (this$id == null) { if (other$id == null) { break Label_0065; } } else if (this$id.equals(other$id)) { break Label_0065; } return false; } final Object this$title = this.getTitle(); final Object other$title = other.getTitle(); Label_0102: { if (this$title == null) { if (other$title == null) { break Label_0102; } } else if (this$title.equals(other$title)) { break Label_0102; } return false; } final Object this$price = this.getPrice(); final Object other$price = other.getPrice(); Label_0139: { if (this$price == null) { if (other$price == null) { break Label_0139; } } else if (this$price.equals(other$price)) { break Label_0139; } return false; } final Object this$author = this.getAuthor(); final Object other$author = other.getAuthor(); Label_0176: { if (this$author == null) { if (other$author == null) { break Label_0176; } } else if (this$author.equals(other$author)) { break Label_0176; } return false; } final Object this$available = this.getAvailable(); final Object other$available = other.getAvailable(); if (this$available == null) { if (other$available == null) { return true; } } else if (this$available.equals(other$available)) { return true; } return false; } protected boolean canEqual(final Object other) { return other instanceof Book; } @Override public int hashCode() { final int PRIME = 59; int result = 1; final Object $id = this.getId(); result = result * 59 + (($id == null) ? 43 : $id.hashCode()); final Object $title = this.getTitle(); result = result * 59 + (($title == null) ? 43 : $title.hashCode()); final Object $price = this.getPrice(); result = result * 59 + (($price == null) ? 43 : $price.hashCode()); final Object $author = this.getAuthor(); result = result * 59 + (($author == null) ? 43 : $author.hashCode()); final Object $available = this.getAvailable(); result = result * 59 + (($available == null) ? 43 : $available.hashCode()); return result; } @Override public String toString() { return "Book(id=" + this.getId() + ", title=" + this.getTitle() + ", price=" + this.getPrice() + ", author=" + this.getAuthor() + ", available=" + this.getAvailable() + ")"; } public Book(@NonNull final String title, @NonNull final Double price) { if (title == null) { throw new NullPointerException("title is marked non-null but is null"); } if (price == null) { throw new NullPointerException("price is marked non-null but is null"); } this.title = title; this.price = price; }} @NoArgsConstructor This annotation generates Default constructor for our class. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.NoArgsConstructor;@NoArgsConstructorpublic class Book { private String id; private String title; private Double price; private String author; private Boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;public class Book{ private String id; private String title; private Double price; private String author; private Boolean available; public Book() { }} @AllArgsConstructor This annotation generates all param constructor for our class. In addition, it generates default constructor if no fields found. If field exists then parameterized constructor is generated. Converted Book.java package com.dev.springboot.lombok.entity;public class Book { private String id; private String title; private Double price; private String author; private Boolean available; public Book(String id, String title, Double price, String author, Boolean available) { this.id = id; this.title = title; this.price = price; this.author = author; this.available = available; } } @Cleanup It will tell Project Lombok to automatically close this resource once it is no longer in use in the current scope like FileInputStream. It ensures the variable declaration that you annotate will be cleaned up by calling its close method, regardless of what happens. Lombok Annotated CleanupTest.java package com.dev.springboot.lombok.entity;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import lombok.Cleanup;public class CleanupTest{ public void test() throws FileNotFoundException, IOException { @Cleanup InputStream in = new FileInputStream("input.txt"); @Cleanup OutputStream out = new FileOutputStream("output.txt"); }} Converted CleanupTest.java package com.dev.springboot.lombok.entity;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.util.Collections;import java.util.List;public class CleanupTest{ public CleanupTest() {} public void test() throws FileNotFoundException, java.io.IOException { InputStream in = new FileInputStream("input.txt"); try { OutputStream out = new FileOutputStream("output.txt"); if (Collections.singletonList(out).get(0) != null) out.close(); } finally { if (Collections.singletonList(in).get(0) != null) in.close(); } }} @Builder In Lombok, the @Builder annotation is used to automatically generate a builder pattern for a class. The builder pattern is a creational design pattern that provides a convenient way to create instances of a class with many attributes, especially when some of those attributes are optional or have default values. @Builder on Constructors: If you want to create Builder for some specific fields, create a parameterized constructor using those fields and apply @Builder on that constructor. @Builder on Methods: Like constructor, If you want to create Builder for some specific fields, create a parameterized method using those fields and apply @Builder to that method. Lombok Annotated Book.java package com.dev.springboot.lombok.entity;import lombok.Builder;@Builderpublic class Book { private String id; private String title; private Double price; private final String author; private Boolean available;} Converted Book.java package com.dev.springboot.lombok.entity;public class Book{ private String id; private String title; private Double price; private final String author; private Boolean available; Book(final String id, final String title, final Double price, final String author, final Boolean available) { this.id = id; this.title = title; this.price = price; this.author = author; this.available = available; } public static Book.BookBuilder builder() { return new Book.BookBuilder(); }} Generated BookBuilder.java package com.dev.springboot.lombok.entity;public static class BookBuilder{ private String id; private String title; private Double price; private String author; private Boolean available; BookBuilder() { } public BookBuilder id(final String id) { this.id = id; return this; } public BookBuilder title(final String title) { this.title = title; return this; } public BookBuilder price(final Double price) { this.price = price; return this; } public BookBuilder author(final String author) { this.author = author; return this; } public BookBuilder available(final Boolean available) { this.available = available; return this; } public Book build() { return new Book(this.id, this.title, this.price, this.author, this.available); } @Override public String toString() { return "Book.BookBuilder(id=" + this.id + ", title=" + this.title + ", price=" + this.price + ", author=" + this.author + ", available=" + this.available + ")"; }} @Synchronized However, @Synchronized is a safer variant of the synchronized method modifier. Like synchronized, the annotation can be used on static and instance methods only. It operates similarly to the synchronized keyword, but it locks on different objects. The keyword locks on this, but the annotation locks on a field named $lock, which is private. If the field does not exist, it is created for you. If you annotate a static method, the annotation locks on a static field named $LOCK instead. Lombok Annotated SynchronizedExample .java package com.dev.springboot.lombok.entity;import lombok.Synchronized;public class SynchronizedExample { private final Object readLock = new Object(); @Synchronized public static void hello() { System.out.println("world"); } @Synchronized public int answerToLife() { return 42; } @Synchronized("readLock") public void foo() { System.out.println("bar"); }} Converted SynchronizedExample.java package com.dev.springboot.lombok.entity;public class SynchronizedExample { private static final Object $LOCK = new Object[0]; private final Object $lock = new Object[0]; private final Object readLock = new Object(); public static void hello() { Object object = $LOCK; synchronized (object) { System.out.println("world"); } } public int answerToLife() { Object object = this.$lock; synchronized (object) { return 42; } } public void foo() { Object object = this.readLock; synchronized (object) { System.out.println("bar"); } }} @SneakyThrows In case of a Java program with exceptions, Java requires that we must either declare or handle a checked exception. Otherwise, the code will show us compilation errors. If we use @SneakyThrows, we don’t have to either declare or handle checked exceptions. Now let’s consider following program which will force us to declare or handle ArithmeticException & ArrayIndexOutOfBoundsException. In fact, if we use @SneakyThrows, we don’t get any compilation errors or warnings. Lombok Annotated SneakyThrowsTest.java package com.dev.springboot.lombok.entity;import lombok.SneakyThrows;public class SneakyThrowsTest { @SneakyThrows({ ArithmeticException.class, ArrayIndexOutOfBoundsException.class }) public static void test() { int a[] = new int[4]; a[4] = 24 / 0; }} Converted SneakyThrowsTest.java package com.dev.springboot.lombok.entity;public class SneakyThrowsTest{ public static void test() { try { try { final int[] a = new int[4]; a[4] = 24 / 0; } catch (ArithmeticException $ex) { throw $ex; } } catch (ArrayIndexOutOfBoundsException $ex2) { throw $ex2; } }} Logging Annotations @CommonsLog, @Slf4j, @Log4j, @Log4j2, @Flogger, @Log, @XSlf4j, @JBossLog There are various Logging Annotations. When applied on the class, they will create a Logger instance as ‘log’ that can be used further in methods. Although we will do this exercise with different Logging libraries. Also, make sure you have included jars as dependency provided in comments of each class mentioned in the below code snippet accordingly. However, we will test all of them in a single class. Subsequently, you are supposed to create a separate class as a particular library you need to implement. Lombok Annotated LoggingTest.java package com.dev.springboot.lombok.entity;import lombok.extern.apachecommons.CommonsLog;import lombok.extern.flogger.Flogger;import lombok.extern.java.Log;import lombok.extern.jbosslog.JBossLog;import lombok.extern.log4j.Log4j;import lombok.extern.log4j.Log4j2;import lombok.extern.slf4j.Slf4j;import lombok.extern.slf4j.XSlf4j;public class LoggerTest{ }@CommonsLogclass CommonsLogTest { // dependency:commons-logging}@Slf4jclass Slf4jLogTest { // dependency:logback-classic}@Log4jclass Log4jLogTest { // dependency:log4j}@Log4j2class Log4j2LogTest { // dependency:log4j-api, log4j-core}@Floggerclass FloggerLogTest { // dependency:flogger, flogger-system-backend}@Logclass LogTest { }@XSlf4jclass XSlf4jLogTest { // dependency:slf4j-ext}@JBossLogclass JBossLogLogTest { // dependency:jboss-logging} Converted LoggerTest.java package com.dev.springboot.lombok.entity;import org.apache.commons.logging.LogFactory;import org.apache.commons.logging.Log;import org.slf4j.LoggerFactory;import org.slf4j.Logger;import org.apache.log4j.Logger;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import com.google.common.flogger.FluentLogger;import java.util.logging.Logger;import org.slf4j.ext.XLoggerFactory;import org.slf4j.ext.XLogger;import org.jboss.logging.Logger;public class LoggerTest{ }class CommonsLogTest{ private static final Log log; static { log = LogFactory.getLog((Class)CommonsLogTest.class); }}class Slf4jLogTest{ private static final Logger log; static { log = LoggerFactory.getLogger((Class)Slf4jLogTest.class); }}class Log4jLogTest{ private static final Logger log; static { log = Logger.getLogger((Class)Log4jLogTest.class); }}class Log4j2LogTest{ private static final Logger log; static { log = LogManager.getLogger((Class)Log4j2LogTest.class); }}class FloggerLogTest{ private static final FluentLogger log; static { log = FluentLogger.forEnclosingClass(); }}class LogTest{ private static final Logger log; static { log = Logger.getLogger(LogTest.class.getName()); }}class XSlf4jLogTest{ private static final XLogger log; static { log = XLoggerFactory.getXLogger((Class)XSlf4jLogTest.class); }}class JBossLogLogTest{ private static final Logger log; static { log = Logger.getLogger((Class)JBossLogLogTest.class); }} FAQ Can we use Lombok API in our real time project ? Yes Of coarse. In fact, many developers who are familiar with this API are using Lombok in their project development to minimize the coding & effort. It also helps us in avoiding habit of writing repetitive code. However, it always depends on your project guidelines whether to use third party API like Lombok or not. Although Lombok can improve code readability and maintainability, its usage may vary depending on the project and team preferences. Some developers prefer to write all code explicitly, while others find Lombok’s features helpful in reducing boilerplate code. Can we customize Lombok-generated methods? Yes, we can customize the behavior of Lombok-generated methods by providing additional annotations or configuring their settings. For example, we can add @NonNull to generate null-checks in setters. Does Lombok have any impact on code quality or maintainability? Lombok can improve code quality by reducing redundancy and making code more concise. However, it’s essential to use it judiciously and consider whether generated methods align with your project’s coding standards and design principles. Can I use Lombok with Java versions older than Java 8? Lombok is primarily intended to use with Java 8 and later versions, as it relies on features like annotations and functional interfaces introduced in Java 8. Although it may work with older Java versions, it is recommended to use it with Java 8 or higher for the best experience. Conclusion We went through all the useful annotations of Lombok Project. Now we should be in a position to use Lombok in our projects. This is all about ‘Lombok Spring Boot and Lombok Annotations’. Further, if there is any update in Lombok API, we will update the article accordingly. If you find anything interesting, don’t hesitate to put your comment. Also, let us know if you have learned something from the article header ‘How To Reduce Boilerplate Code In Java Using Lombok Annotations’. Related
Resources these as the 1 you mentioned right here will be incredibly useful to myself! I will publish a hyperlink to this web page on my personal blog. I am certain my site guests will discover that fairly helpful. Reply
This is a remarkable article by the way. I am going to go ahead and save this post for my brother to read later on tonight. Keep up the fine work. Reply
Took me time to read all of the feedback, but I really loved the article. It proved to be very helpful to me and I am sure to all the commenters right here! I’m positive you had pleasure penning this article. Anyway, in my language, there aren’t a lot good supply like this. Reply
I was questioning in case you can be interested by changing into a guest poster on my weblog? and in exchange you could possibly put a hyperlink the post? Please let me know once you get an opportunity and Ill send you my contact details – thanks. Anyway, in my language, there are not much good source like this. Reply
@Obróbka : Thanks for your feedback. You can connect via ‘Contact Us’ page and please do share link of your weblog. Reply
I like the valuable information you provide in your articles. I’ll bookmark your blog and check again here regularly. I am quite sure I’ll learn many new stuff right here! Reply