Lombok

Posted by:

Project mình đa phần là dùng Maven, Eclipse

<dependencies>
    ...
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
    ...
</dependencies>

Kiểm tra version mới nhất thì vào đây

Cài đặt lombok cho Eclipse

Để khi dùng thư viện lombok mà eclipse không báo lỗi thì cần phải cài đặt lombok cho eclipse, phần này google là ra.

Annotations

@Getter, @Setter, @NoArgsConstructor, @ToString, @EqualsAndHashCode, @Builder, @Data, @Value, @AllArgsConstructor, @Cleanup

1. Getters / Setters, Constructors

@Entity
@Getter 
@Setter 
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class User implements Serializable {
 
    private @Id Long id; // will be set when persisting
 
    private String firstName;
    private String lastName;
    private int age;
 
 
    public User(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }    
}

Một đống annotations: @Getter, @Setter, @NoArgsConstructor, @ToString, @EqualsAndHashCode được thay thế bằng @Data.

@Entity
@Data
public class User implements Serializable {
 
    private @Id Long id; // will be set when persisting
 
    private String firstName;
    private String lastName;
    private int age;
 
 
    public User(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }    
}

Nếu là Immutable classes thì dùng @Value. Immutable class là 1 class sau khi khởi giá trị của nó không thể thay đổi. Lợi ích của immutable class sẽ truy xuất nhanh hơn mutable class và bảo đảm tính nhất quán của dữ liệu.

Đây là một Entity class rất thông thường và phổ biến, lúc nào cũng có getter, setter và constructor không có tham số. Mặc định của getter/setter là private, nếu mình định nghĩa lại là protected field nào thì làm như sau

@Id 
@Setter(AccessLevel.PROTECTED)
private Long id;

@ToString: hay dùng IDE để auto generate, mỗi khi thêm hay xoá bớt fields thì phải xoá và generate lại.

public String toString() {
        return "User(age=" + this.age + ", firstname=" + this.firstname + "....)";
    }

Loại trừ fields: id và age ra khỏi hàm toString thì làm như sau

@ToString(exclude = {"id", "age"})
public class User implements Serializable {
  .....
}

Chú ý: khi dùng @toString có Object lồng Object qua lại lẫn nhau sẽ bị chết.

@Getter
@Setter
@ToString
public class User {
    private String firstName;
    private String lastName;
    private Client client;
}

@Getter
@Setter
@ToString
public class Client {
    private String name;
    private User subordinate;
}

Nếu dùng như vậy sẽ xảy ra lỗi khi gọi user.toString() là StackOverflowError , để fix lỗi này thì

@Getter
@Setter
@ToString(exclude = "client")
public class User {
    private String firstName;
    private String lastName;
    private Client client;
}

@EqualsAndHashCode: sẽ tự động tạo ra hàm equals() và hashCode()

2. Lazy Getters Properties

public class GetterLazy {
 
    @Getter(lazy = true)
    private final Map<String, Long> transactions = readTxnsFromFile();
 
    private Map<String, Long> readTxnsFromFile() { 
        final Map<String, Long> cache = new HashMap<>();
        // Đọc file, xử lý content, trả về map
        ... 
        return cache;
    }
}

3. The Builder Pattern

@Builder
public class ClientConfiguration { 
    // ... everything else remains the same 
}

Cách khởi tạo builder instance làm như sau

ClientConfiguration config = 
    ClientConfiguration.builder()
        .host("api.server.com")
        .port(443)
        .useHttps(true)
        .username("myusername")
        .password("secret")
    .build();

3.@AllArgsConstructor Khởi tạo constructor với đầy đủ parameters là cách fields

@AllArgsConstructor
public class Employee {
    private String name;
    private int salary;
}

delomkok classes, ta có

public class Employee {
    private String name;
    private int salary;
    
    public Employee(String name, int salary) {
        this.name = name;
        this.salary = salary;
    }
}


@Cleanup @Cleanup InputStream is = this.getClass().getResourceAsStream(“res.txt”);

Common uses

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Constants {
    public static final String NAME = "Quach";
} 
@AllArgsConstructor
public enum Direction {
    NORTH("BAC"), 
    SOUTH("NAM"),
    EAST("DONG"),
    WEST("TAY");

    @Getter private String value;
}


0