Lombok is a Java library that can plug into editors and build tools to generate boilerplate code when defining Java classes (such as constructors, field getter and setter, equals and hashCode methods) at compile time for you via annotations

Lets walk through this tutorial to explore in more details

Add Lombok to your project

You can add Lombok into your project as a dependency on pom.xml or build.gradle file. The library versions can be found on the Maven Central Repository

If you use Lombok in a Spring Boot project, the dependency version can be omitted as Spring Boot can help you to resolve

<dependency>  
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>  

Setup Lombok on your IDE, Eclipse and IntelliJ

You may get the highlight errors from the IDEs when coding with Lombok annotations. These errors can be resolved by compiling the project

Apart from that, there's a better way to handle, you can install the Lombok plugin into your IDEs to let them aware that the code will be generated at compile time

With Eclipse, you can download the jar file from Maven Central Repository, double click the downloaded file (right click then click Open on Mac) and click on Install

With IntelliJ, open the IDE Preferences dialog, you can find and install the Lombok plugin by Michail Plushnikov in the Marketplace

Generate constructors

Use @NoArgsConstructor, @RequiredArgsConstructor and @ AllArgsConstructor to generate default constructor (with no arguments), constructor with required (final and @NonNull) fields, constructor with all fields respectively

Given a class which uses the above annotations

import lombok.AllArgsConstructor;  
import lombok.NoArgsConstructor;  
import lombok.NonNull;  
import lombok.RequiredArgsConstructor;

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
public class Product {  
    @NonNull private Integer id;
    private String name;
}

Lombok will generate the above class for you as the following

import lombok.NonNull;

public class Product {  
    @NonNull
    private Integer id;
    private String name;

    public Product() {
    }

    public Product(@NonNull final Integer id) {
        if (id == null) {
            throw new NullPointerException("id is marked @NonNull but is null");
        } else {
            this.id = id;
        }
    }

    public Product(@NonNull final Integer id, final String name) {
        if (id == null) {
            throw new NullPointerException("id is marked @NonNull but is null");
        } else {
            this.id = id;
            this.name = name;
        }
    }
}

Auto constructor injection in Spring

Since Spring 4.3, for classes with only single constructor, you no longer need to specify an explicit injection annotation @Autowired

@RequiredArgsConstructor can be used in conjunction with the above feature. You can see more details in practice with the below example

@Service
@RequiredArgsConstructor
public class ProductService {  
    private final ProductRespository productRespository;

    public Optional<Product> findById(Long id) {
        return productRespository.findById(id);
    }

    ...
}

will generate

@Service
public class ProductService {  
    private final ProductRespository productRespository;

    public ProductService(ProductRespository productRespository) {
        this.productRespository = productRespository;
    }

    public Optional<Product> findById(Long id) {
        return productRespository.findById(id);
    }

    ...
}

Generate getters, setters, toString, equals and hashCode

Use @Getter, @Setter, @ToString, @EqualsAndHashCode to generate field getters and setters, toString, equals and hashCode methods separately

@Getter
@Setter
@ToString
@EqualsAndHashCode
public class Product {  
    private Integer id;
    private String name;
}

will generate

public class Product {  
    private Integer id;

    public Product() {
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(final Integer id) {
        this.id = id;
    }

    public String toString() {
        return "Product(id=" + this.getId() + ")";
    }

    public boolean equals(final Object o) {
        ...
    }

    public int hashCode() {
        ...
    }
}

@Data and @Value

You can also use @Data for the above code generation. @Data is equivalent to @Getter + @Setter + @RequiredArgsConstructor + @ToString + @EqualsAndHashCode

@Data
public class Product {  
    private final Integer id;
    private String name;
}

will generate

public class Product {  
    private final Integer id;
    private String name;

    public Product(final Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

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

    public boolean equals(final Object o) {
        ...
    }

    public int hashCode() {
        ...
    }

    public String toString() {
        return "Product(id=" + this.getId() + ", name=" + this.getName() + ")";
    }
}

Use @Value if you'd like to create an immutable entity. @Value is equivalent to @Getter + @FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) + @AllArgsConstructor + @ToString + @EqualsAndHashCode

@Value
public class Product {  
    private Integer id;
    private String name;
}

will generate

public final class Product {  
    private final Integer id;
    private final String name;

    public Product(final Integer id, final String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public boolean equals(final Object o) {
        ...
    }

    public int hashCode() {
        ...
    }

    public String toString() {
        return "Product(id=" + this.getId() + ", name=" + this.getName() + ")";
    }
}

Add a Logger with @Slf4j

Use @Slf4j to generate a logger field, make sure slf4j-api is already included in your project dependencies

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LogExample {  
}

will generate

import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;

public class LogExample {  
    private static final Logger log = getLogger(LogExample.class);
}

Conclusion

In this tutorial, we learned to plug Lombok into your editors and build tools to generate boilerplate code at compile time when defining Java classes such as constructors, field getters and setters, toString, equals and hashCode methods via annotations

You can find all Lombok features at here