Introdução
Sempre ouço outros desenvolvedores comentarem coisas do tipo: “O java é uma linguagem muito verbosa”, ou comparativos de quantidade de linhas de código do clássico Hello World no java vs Linguagem XPTO. E realmente, quando desenvolvido de maneira pura (sem extensões, plugins etc) comparado a outras linguagens mais novas, o programador acaba tendo que escrever mais para atingir o objetivo. No entanto, há algum tempo, temos uma biblioteca (ou lib) chamada lombok que consegue simplificar (e muito) a vida de quem desenvolve java.
Características
O lombok é uma lib que provê uma coleção de anotações que simplifica algumas tarefas repetitivas do java (como por exemplo, criação de getters e setters). Além de ser uma dependência do seu projeto, ele pluga na sua IDE para que entenda as anotações, portanto ele requer uma configuração. Neste guia irei demonstrar como configurar no eclipse, intellij idea e também no vscode. Caso não saiba como trabalhar com java no vscode veja este post.
O repositório com as classes exemplo estão em: https://github.com/danielpadua/lombok-examples
Pré-requisitos
- Java JDK 8 ou superior
- Eclipse ou IntelliJ IDEA ou vscode
Configuração na IDE
Use as seções abaixo dependendo da IDE que esteja usando:
Eclipse
Faça o download do lombok.jar em: https://projectlombok.org/download, guarde este arquivo em algum diretório de sua máquina (ex.: home do seu usuário). A partir deste ponto existem duas maneiras de configurar no eclipse:
- Execute o arquivo lombok.jar. Irá abrir uma janela onde irá varrer sua máquina em busca de IDEs e caso encontre o eclipse aparecerá uma check-box para habilitar, então clique em instalar e estará feito, conforme imagem abaixo:
Instalação no eclipse via jar
- Caso o método 1 não tenha funcionado ou não encontrado nenhuma IDE, iremos fazer na mão o que o jar faz por trás das cortinas. Abra o arquivo
eclipse.ini
que fica localizado no diretório da configuração do eclipse que você utiliza, edite-o conforme abaixo:
Configurando o lombok no eclipse manualmente
1
-javaagent:<caminho_completo>/lombok.jar
Estamos apenas adicionando o caminho completo jar do lombok como argumento na inicialização do eclipse, e isto fará com que ele entenda o lombok. O jar do lombok faz exatamente este processo, porém copia o jar para dentro da pasta de instalação do eclipse e o vincula no ini de maneira automática
IntelliJ IDEA
É muito simples habilitar suporte do Lombok no IntelliJ IDEA, para isto, basta abrir a seção de instalação de plugins e instalar o plugin destacado a seguir:
Plugin do Lombok no IntelliJ IDEA
Reinicie o IntelliJ IDEA e o suporte do Lombok estará habilitado e funcional.
vscode
Pesquise por lombok na seção de extensões do vscode:
Pesquisa de plugin do lombok no vscode
Instale a extensão do Gabriel Basilio Brito, que por sinal é recomendado pelo próprio site do lombok: https://projectlombok.org/setup/vscode. Reinicie o vscode:
Lombok funcional no vscode
Projeto
Primeiramente devemos criar um projeto java spring-boot, portanto:
Para criar um projeto java spring-boot no eclipse siga este guia.
Para criar um projeto java spring-boot no vscode siga este guia.
Para criar um projeto java spring-boot no intellij idea siga este guia.
Após o projeto criado, use as seções abaixo dependendo da build-tool que você esteja usando:
Maven
Adicione a dependência no arquivo pom.xml
:
1
2
3
4
5
6
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
Pode ser que você tenha que forçar atualização do maven na IDE.
Gradle
Adicione a dependência no arquivo build.gradle
:
1
2
3
4
5
6
7
8
repositories {
mavenCentral()
}
dependencies {
compileOnly ‘org.projectlombok:lombok:1.18.6’
annotationProcessor ‘org.projectlombok:lombok:1.18.6’
}
Utilização
Agora vamos explorar o que o lombok pode fazer para nos ajudar a reduzir o código boilerplate:
Getters, Setters, Construtores, ToString, Equals e HashCode
Para habilitar getter em todos os fields da sua classe, anote sobre a classe: @Getter
.
Para habilitar setter em todos os fields da sua classe, anote sobre a classe: @Setter
.
Para criar um construtor com todos os atributos como parâmetro, anote sobre a classe: @AllArgsConstructor
, sem argumentos: @NoArgsConstrutor
, com argumentos requeridos (ou não-nulos): @RequiredArgsConstructor
Para implementar o toString()
use: @ToString
,
Para implementar o equals()
e hashCode()
use: @EqualsAndHashCode
O @Data
anotado na classe é um atalho para: @ToString
, @EqualsAndHashCode
, @Getter
, @Setter
e @RequiredArgsConstructor
juntos.
Sem lombok:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package br.com.danielpadua.lombok_examples;
public class Dog {
private Integer id;
private String name;
private String breed;
public Dog(Integer id, String name, String breed) {
this.id = id;
this.name = name;
this.breed = breed;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((breed == null) ? 0 : breed.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (breed == null) {
if (other.breed != null)
return false;
} else if (!breed.equals(other.breed))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Dog [id=" + id + ", name=" + name + ", breed=" + breed + "]";
}
}
Com lombok:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package br.com.danielpadua.lombok_examples;
import lombok.Data;
import lombok.NonNull;
@Data
public class Dog {
@NonNull
private Integer id;
@NonNull
private String name;
@NonNull
private String breed;
}
Classes imutáveis
Use a anotação: @Value
sobre a classe, para torná-la imutável
Sem lombok:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package br.com.danielpadua.lombok_examples;
public class DogCreateRequest {
private final String name;
private final String breed;
public DogCreateRequest(final String name, final String breed) {
this.name = name;
this.breed = breed;
}
public String getName() {
return name;
}
public String getBreed() {
return breed;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((breed == null) ? 0 : breed.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DogCreateRequest other = (DogCreateRequest) obj;
if (breed == null) {
if (other.breed != null)
return false;
} else if (!breed.equals(other.breed))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "DogCreateRequest [name=" + name + ", breed=" + breed + "]";
}
}
Com lombok:
1
2
3
4
5
6
7
8
9
package br.com.danielpadua.lombok_examples;
import lombok.Value;
@Value
public class DogCreateRequest {
String name;
String breed;
}
Builder pattern
Use a anotação: @Builder
sobre a classe, para criar o builder pattern
Sem lombok:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package br.com.danielpadua.lombok_examples;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class Kennel {
private Integer id;
private String name;
private Set<Dog> dogs;
public Kennel(Integer id, String name, Set<Dog> dogs) {
this.id = id;
this.name = name;
this.dogs = dogs;
}
public static KennelBuilder builder() {
return new KennelBuilder();
}
public static class KennelBuilder {
private Integer id;
private String name;
private HashSet<Dog> dogs;
KennelBuilder() {
}
public KennelBuilder id(Integer id) {
this.id = id;
return this;
}
public KennelBuilder name(String name) {
this.name = name;
return this;
}
public KennelBuilder dog(Dog dog) {
if (this.dogs == null) {
this.dogs = new HashSet<Dog>();
}
this.dogs.add(dog);
return this;
}
public KennelBuilder dogs(Collection<? extends Dog> dogs) {
if (this.dogs == null) {
this.dogs = new HashSet<Dog>();
}
this.dogs.addAll(dogs);
return this;
}
public KennelBuilder clearDogs() {
if (this.dogs != null) {
this.dogs.clear();
}
return this;
}
public Kennel build() {
Set<Dog> dogs = Collections.unmodifiableSet(this.dogs);
return new Kennel(this.id, this.name, dogs);
}
@Override
public String toString() {
return "KennelBuilder [id=" + id + ", name=" + name + ", dogs=" + dogs + "]";
}
}
}
Com lombok:
1
2
3
4
5
6
7
8
9
10
11
12
13
package br.com.danielpadua.lombok_examples;
import java.util.Set;
import lombok.Builder;
import lombok.Singular;
@Builder
public class Kennel {
private Integer id;
private String name;
@Singular
private Set<Dog> dogs;
}
Logging
Slf4j é um dos suportados, ver: https://projectlombok.org/features/log para todos os suportados
Sem lombok:
1
2
3
4
5
6
7
8
9
10
11
package br.com.danielpadua.lombok_examples;
public class App
{
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(App.class);
public static void main( String[] args )
{
log.info( "Hello World!" );
}
}
Com lombok:
1
2
3
4
5
6
7
8
9
10
11
package br.com.danielpadua.lombok_examples;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class App {
public static void main(String... args) {
log.info("Hello world");
}
}
Conclusão
Apesar do tempo de setup e configuração gasto, o lombok foi desenvolvido pensando em aumentar a produtividade do desenvolvedor java. Venho utilizando esta lib há algum tempo e não penso em deixar de usá-la.
Até a próxima!