Empezar con lombok

De ChuWiki
Saltar a: navegación, buscar

Veamos algunas cosas básicas de lombok. Tienes los ejemplos en lombok-example

Getter y Setter

Una de las cosas engorrosas de hacer son los setter y getter de las clases. Con lombok nos bastaría con poner la anotación @Setter y @Getter en la clase para tener métodos setter y getter de todos los atributos

package com.chuidiang.lombok_example;

import lombok.*;

/**
 * @author fjabellan
 * @date 21/11/2020
 */
@Getter
@Setter
public class Data {
    private int anInteger;
    private String anString;
}

Listo, con esto deberíamos tener los métodos set y get de anInteger y anString.

Si no los quremos todos, podemos luego añadir excepciones con anotaciones en los atributos concretos. Por ejemplo, si en el código anterior añadimos la siguiente anotación en el atributo anString

    @Getter(value=AccessLevel.NONE)
    private String anString;

no se generará el getter. Con AccessLevel tenemos además opciones para hacer el getter protegido o privado.

También podemos no poner la anotación Getter y/o Setter en la clase y ponerla en los atributos que nos interesen.

Constructores

Los constructores que llevan parámetros para meter en los atributos también son bastante repetitivos. Bastaría con poner algo como esto

package com.chuidiang.lombok_example;

import lombok.*;

/**
 * @author fjabellan
 * @date 21/11/2020
 */
@AllArgsConstructor
@NoArgsConstructor
public class Data {
    private int anInteger;
    private String anString;
}

Con la anotación @AllArgsConstructor tenemos disponible un constructor con todos los atributos, en el orden que aparecen. Si queremos mantener un constructor sin parámetros, debemos añadir la anotación @NoArgsConstructor

Tenemos otra anotación posible adicional, @RequiredArgsConstructor. Este analiza los atributos de la clase para ver cuales es obligatorio rellenar en el constructor (por ejemplo, atributos final que no estén inicializados) o que tengan la anotación @NonNull

toString

Podemos hacer de forma fácil un método toString()

package com.chuidiang.lombok_example;

import lombok.*;

/**
 * @author fjabellan
 * @date 21/11/2020
 */
@ToString
public class Data {
    private int anInteger;
    private String anString;
}

Esto nos da un método toString que saca todos los atributos. En nuestro ejemplo, la salida del método toString() sería

Data(anInteger=10, anString=10)

suponiendo que hubieramos puesto como valores 10 y "10" para el entero y el string respectivamente.

Podemos decidir qué campos queremos en el toString() en la anotación, poniéndola de esta manera

@ToString(of={"anInteger","anString"})

equals y hashcode

El método equals() y hashCode() se pueden hacer también con anotaciones

package com.chuidiang.lombok_example;

import lombok.*;

/**
 * @author fjabellan
 * @date 21/11/2020
 */
@EqualsAndHashCode
public class Data {
    private int anInteger;
    private String anString;
}

esto haría que los métodos equals() y hashCode() tengan en cuenta todos los atributos de la clase para decidir si dos instancias de la clase son iguales o distintas.

De la misma forma que en toString(), podemos decidir qué campos queremos que intervengan en el equals/hashcode.

<syntaxhightlight lang="java"> @EqualsAndHashCode(of={"anInteger"}) </syntaxhighlight>

Data

Habitualmente una clase puede ser simplemente una estructura de datos y suele ser útil que tenga todo esto: setter, getter, equals y hashcode, constructores y toString. La anotación @Data equivale a todas ellas.

<syntaxhightlight lang="java"> package com.chuidiang.lombok_example;

import lombok.*;

/**

* @author fjabellan
* @date 21/11/2020
*/

@Data public class Data {

   private int anInteger;
   private String anString;

} </syntaxhighlight>

Con esto tenemos todo, con las opciones por defecto.

slf4j

Declarar el logger suele ser también un poco engorroso. En cada clase hay que poner algo del estilo

   private static final Logger log = LoggerFactory.getLogger(Data.class);
</syntaxhightlight>

Con lombok y en el caso de usar la librería slf4j para logger, se pondría la anotación así

<syntaxhighlight lang="java">
package com.chuidiang.lombok_example;

import lombok.extern.slf4j.Slf4j;

/**
 * @author fjabellan
 * @date 21/11/2020
 */
@Slf4j
public class SomeProcess {
    public void doSomething(){
        log.info("I'm doing something");
    }
}

y tenemos el log disponible sin necesidad de declararlo.

Dependencias

Si usamos lombok, anotamos las clases con determinadas anotaciones de lombok para ahorrarnos escribir código. Cosas como setter, getter, constructores, método toString, métodos hashCode y equals, etc podemos ahorrarnos escribirlos sin más que anotar las clases. Durante el compilado, lombok analiza las anotaciones y genera el código que le hemos indicado en las anotaciones. El código en ningún momento lo veremos en los fuentes de java.

Este procedimiento de mirar anotaciones durante el compilado y hacer "cosas" lo soporta java mediante los "annotation processor" o procesadores de anotaciones. lombok tiene uno o es un ejemplo concreto de annotation processor, pero hay más.

Con gradle o maven necesitamos dos "dependencias". Por un lado, la que nos permite tener las anotaciones disponibles en nuestro código. Por otro la que añade ese annotation processor al proceso de compilado. La primera dependencia no la necesitamos en tiempo de ejecución, solo durante el compilado. La segunda tres cuartos de lo mismo. Veamos detalles

gradle

En gradle (6.x.x), las dependencias serían estas

dependencies {
    compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.16'
    annotationProcessor 'org.projectlombok:lombok:1.18.16'
    ...
}

La primera es la que tiene las anotaciones. La dependencia es tipo "compileOnly" porque solo la necesitamos durante el proceso de compilado. Este tipo de dependencia "compileOnly" evita que si más adelante hacemos un zip de distribución de nuestra aplicación con gradle, venga el jar de lombok dentro del zip.

La segunda es el "annotationProcessor". Le dice a gradle que tiene que usarlo al compilar y así lombok hace su magia: generar dentro de la clase compilada el código ya compilado que no hemos querido poner en los fuentes.

maven

Para maven (3.6.3) las dependencias serían estas

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

y ya está, maven es un poco más listo (o menos configurable) y no necesita lo del annotationProcessor, lo incluye directamente de la dependencia.

El IDE

Para que nuestro IDE favorito (eclipse, idea, ..) sepa que hay código que no está (setter, getter, constructores, ...) y no nos marque las líneas en rojo cuando las usamos, posiblemente hay que habilitarle el annotationProcessing. Los IDE suelen tener alguna ventana en la configuración del proyecto donde se habilita esta opción o incluso añadir algún plugin adicional

Por ejemplo, en el caso de idea, es necesario añadir el plugin de lombok

Idea-lombok-plugin.png

y además hablitar el annotation processing

Idea-annotation-processor.png