Usando anotações do Lombok em Java com SpringBoot

Marcos
6 min readJan 18, 2021

--

Uma classe java eventualmente pode ficar enorme. Sei que não é o ideal mas pode acontecer, não algo com milhares de linhas semelhante ao que pode acontecer em linguagens não orientadas a objetos, mas uma quantidade que fique um pouco desconfortável para ler na tela. Para pegar essa ideia dê uma olhada nesse exemplo:

import java.util.Date;
import java.util.Objects;

public class Pessoa {
public Pessoa(String nome, String cpf, String apelido, Date dataNascimento, int idade) {
this.nome = nome;
this.cpf = cpf;
this.apelido = apelido;
this.dataNascimento = dataNascimento;
this.idade = idade;
}
private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;

public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}

public String getCpf() {
return cpf;
}

public void setCpf(String cpf) {
this.cpf = cpf;
}

public String getApelido() {
return apelido;
}

public void setApelido(String apelido) {
this.apelido = apelido;
}

public Date getDataNascimento() {
return dataNascimento;
}

public void setDataNascimento(Date dataNascimento) {
this.dataNascimento = dataNascimento;
}

public int getIdade() {
return idade;
}

public void setIdade(int idade) {
this.idade = idade;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pessoa pessoa = (Pessoa) o;
return idade == pessoa.idade &&
Objects.equals(nome, pessoa.nome) &&
Objects.equals(cpf, pessoa.cpf) &&
Objects.equals(apelido, pessoa.apelido) &&
Objects.equals(dataNascimento, pessoa.dataNascimento);
}

@Override
public int hashCode() {
return Objects.hash(nome, cpf, apelido, dataNascimento, idade);
}

@Override
public String toString() {
return "Pessoa{" +
"nome='" + nome + '\'' +
", cpf='" + cpf + '\'' +
", apelido='" + apelido + '\'' +
", dataNascimento=" + dataNascimento +
", idade=" + idade +
'}';
}
}

Essa é uma classe simples que representa uma pessoa em um programa java. Agora, repare que eu não coloquei dados de endereço, cidade de nascimento etc. Essas informações gerariam classes parecidas e mais linhas nessa mesma classe.

Agora repare na mesma classe usando anotações do Lombok:

import lombok.*;
import java.util.Date;

@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;

}

Muito menor né? Ficou mais fácil para ler.

Agora que a ideia foi passada, vamos instalar e ver um pouco do que o Lombok pode nos oferecer.

Instalando:

O site do lombok é esse: https://projectlombok.org/, mas para utilizá-lo em um projeto maven basta adicionar a dependência no pom.xml:

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

Feito isso, o jar do lombok será adicionado ao projeto por causa do gerenciamento de dependências do maven.

Difícil né?

Bora usar essas anotações então.

@ Getter e @ Setter

Sobre “@ Getter” e “@ Setter” : São as anotações que fornecem os métodos getters e setters para atributos privados.

@Getter
@Setter
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;

}

Essas anotações podem ter um parâmatro para indicar o tipo de acesso aos dados (public ou protected), então elas podem ficar assim:


@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;

}

As anotações desse jeito significam isso:

import lombok.*;
import java.util.Date;

public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;

protected String getNome() {
return nome;
}

protected void setNome(String nome) {
this.nome = nome;
}

protected String getCpf() {
return cpf;
}

protected void setCpf(String cpf) {
this.cpf = cpf;
}

protected String getApelido() {
return apelido;
}

protected void setApelido(String apelido) {
this.apelido = apelido;
}

protected Date getDataNascimento() {
return dataNascimento;
}

protected void setDataNascimento(Date dataNascimento) {
this.dataNascimento = dataNascimento;
}

protected int getIdade() {
return idade;
}

protected void setIdade(int idade) {
this.idade = idade;
}
}

Também podem ser usadas em cima do atributo, dependendo da lógica/finalidade utilizada.

@ NonNull

Essa anotação fornece um teste rápido pra verificar se um atributo é nulo, ajudando a evitar NullPointerException.

Exemplo de uso:

import lombok.*;
import java.util.Date;

@ToString
@Getter
@Setter
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;

}

@ ToString

Essa anotação gera uma implementação do método toString. É Só isso.

Exemplo de uso:

import lombok.*;
import java.util.Date;

@ToString
@Getter
@Setter
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;

}

@ EqualsAndHashCode

Fornece os métodos equals() e hachCode().

É possível personalizar os atributos que serão validados, exemplos de uso:

import lombok.*;
import java.util.Date;

@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(exclude={"dataNascimento","idade"})
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;
}

Ou:

@ToString
@Getter
@Setter
@EqualsAndHashCode
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;
}

@ Data

Essa anotação é a combinação das anotações: @ ToString, @EqualsAndHashCode, @ Getter e @ Setter. Também fornece a geração de construtores, adicionando um construtor público que leva qualquer campo @NonNull ou final como parâmetros.

Mas como já visto aqui, caso queira personalizar melhor os métodos é aconselhável usar as anotações de cada funcionalidade com seus parâmetros.

@ NoArgsConstructor

Fornece a criação de um construtor vazio, exemplo de uso:

@ToString
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
@NoArgsConstructor
@EqualsAndHashCode
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;

}

Código equivalente:

@ToString
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
@EqualsAndHashCode(exclude={"dataNascimento","idade"})
public class Pessoa {

public Pessoa (){

}

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;

}

@ AllArgsConstructor

Fornece a criação de um construtor com todos os atributos, exemplo de uso:

@ToString
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Pessoa {

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;

}

Código equivalente:

@ToString
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
@EqualsAndHashCode(exclude={"dataNascimento","idade"})
public class Pessoa {

public Pessoa(String nome, String cpf, String apelido, Date dataNascimento, int idade, Endereco endereco) {
this.nome = nome;
this.cpf = cpf;
this.apelido = apelido;
this.dataNascimento = dataNascimento;
this.idade = idade;
this.endereco = endereco;
}

private String nome;
private String cpf;
private String apelido;
private Date dataNascimento;
private int idade;
@NonNull
private Endereco endereco;

}

É possível definir o tipo de acesso do construtor gerado, se liga nesse print:

Também é possível a criação de um construtor estático:

Por fim, trouxe mais duas anotações bem úteis.

@ RequiredArgsConstructor

Essa anotação é muito útil na hora de fazer a injeção de dependência, exemplo de uso:

@Component
@RequiredArgsConstructor
public class PessoaGatewayImpl {

private final PessoaRepository pessoaRepository;

public void save(Pessoa pessoa){
pessoaRepository.save(pessoa);
}

}

O objeto do tipo final foi injetado via construtor usando essa anotação. Pode ser usada para substituir “@ AutoWired” e “@ Inject”.

@ Slf4j

Cria o atributo private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger (PessoaGatewayImpl.class). Exemplo de uso:

@Slf4j
@Component
@RequiredArgsConstructor
public class PessoaGatewayImpl {

private final PessoaRepository pessoaRepository;

public void save(Pessoa pessoa){
log.info("Armazenando informação.");
pessoaRepository.save(pessoa);
}

}

Código equivalente:

import br.com.example.entity.Pessoa;
import br.com.example.gateway.database.repository.PessoaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class PessoaGatewayImpl {

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger (PessoaGatewayImpl.class);

private final PessoaRepository pessoaRepository;

public void save(Pessoa pessoa){
log.info("Armazenando informação.");
pessoaRepository.save(pessoa);
}

}

O Lombok tem mais anotações, mas no dia a dia costumo usar essas dentro dos programas que desenvolvo.

Esse código está no github: https://github.com/mmarcosab/lombokexample mas não esperem nada dele além das coisas vistas nesse texto.

Até mais.

Fontes: https://projectlombok.org/

--

--

Marcos
Marcos

Written by Marcos

I study software development and I love memes.

No responses yet