Pretpostavimo da moramo kreirati klasu sa osam atributa. Za svaki od tih atributa potrebno je da napravimo  getter i setter metode. Osim ovih metoda, obično moramo napisati i potrebne konstruktore, toString(), equals()hashCode()metode. To znači da je za klasu sa osam atributa potrebno kreirati ni više ni manje nego devetnaest metoda i konstruktore, što čini tu klasu nepreglednom i komplikovanom za održavanje. Lombok je java biblioteka koja omogućava smanjenje koda unutar klasa. Lombok se koristi za automatsko generisanje objektnog koda uz pomoć anotacija. U ovom članku će biti prikazana upotreba Lombok-a kroz par primjera.

Lombok možemo dodati u svoje maven java projekte dodavajući u pom.xml sljedeći dependency:

Nakon što dodamo dependency, potrebno je da odaberemo lombok anotacije koje želimo koristiti. Lombok funkcioniše na način da se tokom build process-a, automatski generiše Java bytecode u .class datoteke u skladu sa odabranim anotacijama.

Osim toga bilo da koristimo IntelliJ IDEA ili Eclipse ili neko drugo IDE, potrebno je da instaliramo i lombok plugin. Iako se prilikom build process-a automatski generiše Java bytecode u skladu sa odabranom lombok anotacijom, IDE ne vidi taj generisan kod i prijavit će nam kompajlersku grešku. Ovaj slučaj je prikazan na sljedećoj slici:

Sada kad nam je poznat način funkcionisanja Lombok-a, opisat ćemo par Lombok anotacija.

Ukoliko želimo da spriječimo da nam se pomoću konstruktora ili setter-a postavi null kao vrijednost nekog polja, za to polje možemo staviti lombok anotaciju @NonNull.

Anotacija @ToString se koristi da generiše toString() metodu za klasu User. Anotacije @Getter i @Setter služe da generišu getter-e i setter-e za sva polja klase User, koja nisu final. Ukoliko polje ima anotaciju @NonNull, anotacija @Setter vrši provjeru da li je vrijednost, koju će to polje primiti, u skladu sa tim ograničenjem.

Anotacija @NoArgsConstructor generiše kontruktor bez parametara za tu klasu. Bitno je naglasiti za ovu anotaciju da ukoliko su sva polja unutar final klase, kontruktor bez parametara se neće izgenerisati i build proces će završiti sa greškom. Pojavljivanje ove greške se može izbjeći ukoliko property force postavimo na true, unutar anotacije (@NoArgsConstructor (force=true)).

package org.infobip.example.models;

import lombok.*;

@ToString
@NoArgsConstructor
@Getter
@Setter
public class User {
    private String name;
    private String surname;
    private String username;
    private String password;
    private String email;
    private String telephone;
    private String address;
}

 

Nakon što se završi build proces u .class folderu možemo pronaći klasu na kojoj smo primjenili anotacije i vidjeti da je stvarno izgenerisan kod za odabrane anotacije. U našem primjeru izgenerisan kod možemo pronaći u target/classes/org/infobip/example/models/User.class.

Osim anotacije @NoArgsConstructor, lombok sadrži anotacije @RequiredArgsConstructor i @AllArgsConstructor za generisanje konstruktora. Prilikom upotrebe anotacija @RequiredArgsConstructor i @AllArgsConstructor za generisanje konstruktora, kontruktor će izvršiti provjeru null vrijednosti. Ukoliko polje ima ograničenje da ne može biti null (lombok-ova anotacija @NonNull), konstruktor će pri kreiranju baciti NullPointerException. @AllArgsConstructor generiše konstruktor sa po jednim parametrom za svako polje klase. Upotreba ove anotacije je prikazana na sljedećem primjeru:

package org.infobip.example.models;

import lombok.*;

@AllArgsConstructor
public class User {
    private @NonNull  String name;
    private String surname;
    private String username;
    private String password;
    private String email;
    private String telephone;
    private String address;
}

 

@RequiredArgsConstructor kreira konstruktor sa po jednim parametrom za sva polja koja su final, a nisu već inicijalizirana i za polja koja imaju anotaciju @NonNull. Osim mogućnosti generisanja konstruktora za sve parametre, konstruktora bez parametara, setter-a, lombok nudi mogućnost generisanja builder-a za tu klasu, na osnovu Builder design patterna. To je moguće ukoliko stavimo anotaciju @Builder iznad te klase i onda nema potrebe da pišemo dodatnu Builder klasu.

package org.infobip.example.models;

import lombok.*;

@Builder
public class User {
    private @NonNull  String name;
    private String surname;
    private String username;
    private String password;
    private String email;
    private String telephone;
    private String address;
}

 

U narednom primjeru je prikazano kako možemo postaviti vrijednosti polja te klase, nakon što smo stavili anotaciju @Builder.

package org.infobip.example.services;

import lombok.extern.slf4j.Slf4j;
import org.infobip.example.models.User;

@Slf4j
public class UserService {

    public static void main(String[] args) {
        User example1 = User.builder()
                            .address("Aleja lipa")
                        .build();
        User example2 = User.builder()
                            .address("Aleja lipa")
                            .email("Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je vidjeli.")
                            .name("Ilvana")
                        .build();
        User example3 = User.builder()
                            .password("ilvana")
                            .username("izajimovic")
                            .email("Ova adresa el. pošte je zaštićena od spambotova. Omogućite JavaScript da biste je vidjeli.")
                            .telephone("38761585254")
                            .surname("Zajimovic")
                        .build();
        User example4 = User.builder().build();
    }
}

 

Na ovom primjeru je pokazana primjena anotacije @Data. Anotacija @Data u sebi sadrži anotacije: @ToString, @EqualsAndHashCode, @Getter (za sva polja) i @Setter (za sva polja koja nisu final) i anotaciju @RequiredArgsConstructor.

package org.infobip.example.models;

import lombok.*;

@Data
public class User {
    private String name;
    private String surname;
    private String username;
    private String password;
    private String email;
    private String telephone;
    private String address;
}

 

Obično kada želimo instancirati Logger iz Slf4j framework-a, uradimo to na sljedeći način:

package org.infobip.example.services;

import org.infobip.example.models.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserService {
    private static Logger log = LoggerFactory.getLogger(UserService.class);
    
    public void create(User user){
        log.info("Creating user...");
    }
}

 

Lombok nam omogućava instanciranje Logger-a iz Slf4j frameworka pomoću anotacije @Slf4j.

package org.infobip.example.services;

import lombok.extern.slf4j.Slf4j;
import org.infobip.example.models.User;

@Slf4j
public class UserService {
    public void create(User user){
        log.info("Creating user...");
    }
}

 

Ista stvar je i sa instanciranjem Logger-a iz Jboss framework-a. Bez Lombok-a bi to uradili na sljedeći način:

package org.infobip.example.services;

import org.infobip.example.models.User;
import org.jboss.logging.Logger;

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

    public void create(User user){
        log.info("Creating user...");
    }
}

 

A sa Lombok-om uz pomoć anotacije @JbossLog na sljedeći način:

package org.infobip.example.services;

import lombok.extern.jbosslog.JBossLog;
import org.infobip.example.models.User;

@JBossLog
public class UserService {
    public void create(User user){
        log.info("Creating user...");
    }
}

 

Lombok posjeduje anotacije za instanciranje Logger i iz drugih framework-a.  

@CommonLogs instancira

 private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(UserService.class);

 

@Log instanicira

 private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(UserService.class.getName());

 

@Log4j instancira

private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(UserService.class);

 

@Log4j2 instancira

private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(UserService.class);

@XSlf4j
 instancira
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XloggerFactory.getXLogger(UserService.class);
 

Kako bi se izbjeglo stalno ponavljanje try/catch blokova, može se upotrijebiti lombok anotacija @SneakyThrowsStandardan način rukovanja sa izuzecima je prikazan u sljedećem primjeru:

package org.infobip.example.util;

import java.io.UnsupportedEncodingException;

public class UserServiceHelper {
    public String utf8ToString(byte[] bytes) {
        try {
            return new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
           throw new RuntimeException();
        }
    }
}

 

Koristeći lombok anotaciju @SneakyThrows, prethodni primjer možemo napisati na sljedeći način:

package org.infobip.example.util;

import lombok.SneakyThrows;

public class UserServiceHelper {
    @SneakyThrows( UnsupportedEncodingException.class)
    public String utf8ToString(byte[] bytes) {
        return new String(bytes, "UTF-8");
    }
}

 

Za više detalja o Lomboku pogledajte dokumentaciju na sljedećem linku: http://www.baeldung.com/intro-to-project-lombokKod koji je korišten u primjerima možete pronaći na sljedećem linku: https://github.com/Ilvana/infobip-exampleDo narednog čitanja!

 

Ilvana Zajimović, Infobip BH d.o.o.

 

1/1