J'ai une classe appelée "XYZClientWrapper", qui a la structure suivante:
@Builder
XYZClientWrapper{
String name;
String domain;
XYZClient client;
}
Ce que je veux, aucune fonction de génération générée pour la propriété XYZClient client
Est-ce que Lombok prend en charge un tel cas d'utilisation?
Oui, vous pouvez placer @Builder sur un constructeur ou une méthode statique (fabrique) contenant uniquement les champs de votre choix.
Divulgation: Je suis un développeur de Lombok.
Sinon, j'ai découvert que le marquage d'un champ par final , static ou static final indique à @Builder
d'ignorer ce champ.
@Builder
public class MyClass {
private String myField;
private final String excludeThisField = "bar";
}
Lombok 1.16.10
J'ai constaté que j'étais capable d'implémenter un "Shell" de la classe Builder statique, d'ajouter la méthode que je veux masquer avec un modificateur d'accès privé et qu'elle n'est plus accessible dans le générateur. De même, je peux également ajouter des méthodes personnalisées au générateur.
package com.something;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import Java.time.ZonedDateTime;
@Data
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyClass{
//The builder will generate a method for this property for us.
private String anotherProperty;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "localDateTime", column = @Column(name = "some_date_local_date_time")),
@AttributeOverride(name = "zoneId", column = @Column(name = "some__date_zone_id"))
})
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private ZonedDateTimeEmbeddable someDateInternal;
public ZonedDateTime getSomeDate() {
return someDateInternal.toZonedDateTime();
}
public void setSomeDate(ZonedDateTime someDate) {
someDateInternal = new ZonedDateTimeEmbeddable(someDate);
}
public static class MyClassBuilder {
//Prevent direct access to the internal private field by pre-creating builder method with private access.
private MyClassBuilder shipmentDateInternal(ZonedDateTimeEmbeddable zonedDateTimeEmbeddable) {
return this;
}
//Add a builder method because we don't have a field for this Type
public MyClassBuilder someDate(ZonedDateTime someDate) {
someDateInternal = new ZonedDateTimeEmbeddable(someDate);
return this;
}
}
}
Créez le générateur dans le code et ajoutez un passeur privé pour votre propriété.
@Builder
XYZClientWrapper{
String name;
String domain;
XYZClient client;
public static class XYZClientWrapperBuilder {
private XYZClientWrapperBuilder client(XYZClient client) { return this; }
}
}
Exemple de méthode statique en usine
Class Car{
private String name;
private String model;
private Engine engine; // we want to ignore this
@Builder
public static Car of(String name, String model){
Car car=new Car();
car.setName(name);
car.setModel(model);
constructEngine(); // some private method to construct engine internally
return car;
}
private constructEngine(){// construct engine internally}
}
alors vous pouvez utiliser comme suit:
main(String[] args){
Car toyotaCorollaCar=Car.builder().name("Toyota").model("Corolla");
// You can see now that Car.builder().engine() is not available
}
Notez que la méthode statique of
sera appelée chaque fois que build () est appelé. Par conséquent, une action telle que Car.builder().name("Toyota")
ne définit pas la valeur "Toyota"
dans name
à moins que build()
ne soit appelé, puis l'assignation de la logique dans la méthode statique constructeur of
est exécutée.
Voici ma solution préférée. Avec cela, vous pouvez créer votre champ client
à la fin et le définir en fonction d'autres champs préalablement définis par le générateur.
XYZClientWrapper{
String name;
String domain;
XYZClient client;
@Builder
public XYZClientWrapper(String name, String domain) {
this.name=name;this.domain=domain;
this.client=calculateClient();
}
}