Lombok etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Lombok etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

13 Nisan 2023 Perşembe

Lombok @NoArgsConstructor Anotasyonu - Default Constructor Yaratır

Örnek
Şöyle yaparız
@Getter
@Setter
@NoArgsConstructor
public class Car {
  private String manufacturer;
  private String model;
  private String engineType;
  private Integer power;
}

12 Şubat 2023 Pazar

Lombok @Cleanup Anotasyonu

Giriş
Açıklaması şöyle
This is, perhaps, one of the least used Lombok annotations. This can be used on the classes that do implement the Closable interface and it will be similar to the try-with-resources block.

Lombok @Log Anotasyonu - JUL Logging İçindir

Giriş
Açıklaması şöyle
This annotation is used for applications relying on the java.util.logging framework. Similar to @Slf4j, it provides a static logger instance named log.
Örnek
Şöyle yaparız
@Log
public class LegacyService {
  public void legacyMethod() {
    log.info("Legacy method logged with @Log");
  }
}

Lombok @Synchronized Anotasyonu

Giriş
Açıklaması şöyle
If we need to synchronize method calls, we can use Lombok’s annotation instead of the synchronized Java keyword for a safer implementation:

7 Aralık 2022 Çarşamba

Lombok @With Anotasyonu

Giriş
Şu satırı dahil ederiz
import lombok.With;
Açıklaması şöyle
If we use immutable classes, we can annotate their fields with @With and the equivalent of a setter will be generated. The difference is that the with-er method will return a completely new instance of the object, with one of the fields updated. This annotation can be extremely useful for Java 17’s records
Örnek
Şöyle yaparız
public record User (
  String firstName,
  String lastName,
  Long id,
  @With String email
);

User.withEmail ("...")

3 Ağustos 2022 Çarşamba

Lombok @Accessors Anotasyonu - @Getter ve @Setter'ları Fluent Yapar

Giriş
Şu satırı dahil ederiz
import lombok.experimental.Accessors;
chain Alanı
Setter'lar void yerine this döner.
Örnek
Şöyle yaparız
@Data @Accessors(chain = true, fluent = true) public class Student { private String firstName; private String lastName; private String studentId; private Integer year; private List<Integer> marks; public Student(@NonNull String firstName) { this.firstName = firstName; this.studentId = generateStudentId(firstName); } private String generateStudentId(String firstName) { return firstName + new Random().nextInt(1_000); } } Student student = new Student("John").lastName("Doe").year(2);
fluentAlanı
Getter ve Setter'lar getX(), setX() yerine direkt alan ismini kullanırlar. Yani sadece x()

13 Nisan 2021 Salı

Lombok @Singular Anotasyonu

Giriş
Şu satırı dahil ederiz
import lombok.Singular;
Açıklaması şöyle
When the @Singular annotation is placed on a collection property, Lombok creates special builder methods to individually add items to that collection, rather than adding the entire collection at once. This is particularly nice for tests as creating small collections in Java is not concise.
Örnek
Şöyle yaparız
@Value
@Builder(toBuilder = true)
public class User {
  @NonNull
  UUID userId;
  @NonNull
  String email;
  @Singular
  Set<String> favoriteFoods;
  @NonNull
  @Builder.Default
  String avatar = “default.png”;
}

User user = User.builder()
  .userId(UUID.random())
  .email(“grubhub@grubhub.com”)
  .favoriteFood(“burritos”)
  .favoriteFood(“dosas”)
  .build()

Lombok @FieldDefaults Anotasyonu - Üye Alanları Örneğin Private ve Final Yapar

Giriş
Şu satırı dahil ederiz
import lombok.experimental.FieldDefaults;
Açıklaması şöyle
This annotation provides a way to set default modifiers for the fields in a class. You can control the access level of fields and specify whether they should be final. This is particularly useful in Spring-based applications where you might want to establish consistent field-level access control without explicitly declaring it for each field.
Açıklaması şöyle
When you annotate a class with @FieldDefaults, you can specify two key elements:

Access Level: The visibility of the fields, such as PRIVATE, PROTECTED, PACKAGE, or PUBLIC. The default value is PRIVATE.
Final: A Boolean value specifying whether the fields should be final. The default is false.

makeFinal Alanı
Açıklaması şöyle. Yani @Data ile üretilecek setter metodları engelleyebilir
Setting makeFinal = true works well when you are creating immutable classes, but it does limit the functionality of other Lombok annotations like @Setter. In classes annotated with @Data, the makeFinal = true setting will essentially disable the generation of setter methods, because final fields cannot be modified once initialized.
Örnek
Şöyle yaparız
import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.AccessLevel; @Data @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class SecureBook { String title; String author; int pages; }
Örnek
Elimizde şöyle bir kod olsun
@Slf4j
@RequiredArgsConstructor
@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE)
public class UserService {
  @NonNull UserDao userDao;
}
Açıklaması şöyle
The @FieldDefaults annotation adds the final and private modifiers to all of the fields. 





Lombok @UtilityClass Anotasyonu

Giriş
Açıklaması şöyle
@UtilityClass annotation which creates a private constructor that throws an exception, makes the class final, and makes all methods static.
Örnek
Şöyle yaparız
@UtilityClass
// will be made final
public class UtilityClass {
  // will be made static
  private final int GRUBHUB = “ GRUBHUB”;

  // autogenerated by Lombok
  // private UtilityClass() {
  //   throw new java.lang.UnsupportedOperationException("... cannot be instantiated");
  //}

  // will be made static
  public void append(String input) {
    return input + GRUBHUB;
  }
}

Lombok @Value Anotasyonu - Record Gibidir

Giriş
Açıklaması şöyle
@Value is similar to @Data except, all fields are made private and final by default and setters are not generated. These qualities make @Value objects effectively immutable. As the fields are all final, there is not a no argument constructor. Instead Lombok uses @AllArgsConstructor to generate an all arguments constructor. This results in a fully-functioning, effectively-immutable object.
Açıklaması şöyle
 Short for final @ToString, @EqualsAndHashCode, @AllArgsConstructor,   @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE), @Getter.

21 Ocak 2021 Perşembe

Lombok @NonNull Anotasyonu - @NotNull Değil !

Giriş
Şu satırı dahil ederiz
import lombok.NonNull;
Açıklaması şöyle
Makes sure the value of object is not null. This is highly beneficial when dealing with data access object and saves risk NullPointerException that may go unchecked.
Kalıtan sınıflarda kullanırken dikkatli olmak lazım

Örnek
Şöyle yaparız
public record User (
  @NonNull String firstName,
  String lastName,
  Long id,
  String email) {
}
Örnek
Şöyle yaparız
import lombok.NonNull;

public class Foo {
  protected final String name;
    
  public Foo(@NonNull final String name) {
    this.name = name;
  }
}

11 Ocak 2021 Pazartesi

Lombok Kullanımı

Giriş
IntelliJ'de File/Settings menüsü kullanılarak Builder,Execution,Deployment ayarlarına gelinir. Compiler/Annotation Processors seçeneği seçilir ve "Enable Annotation processing" etkinleştirilir.

Maven
Şöyle yaparız
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.18</version>
  <scope>provided</scope>
</dependency>
Açıklaması şöyle
... Lombok is needed only at compile time. Because of that reason, the maven scope can (and should) be set to compile/provided.
Normalde bu gerekli değil ancak annotation processor'lara sıra vermek istersek şöyle yaparız
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <source>1.8</source> <!-- depending on your project -->
        <target>1.8</target> <!-- depending on your project -->
        <annotationProcessorPaths>
          <path>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
  </plugins>
</build>
Gradle
Örnek
Şöyle yaparız
compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.26'
Örnek
Şöyle yaparız
dependencies {
  compileOnly 'org.projectlombok:lombok:1.18.22'
  annotationProcessor 'org.projectlombok:lombok:1.18.22'
	
  testCompileOnly 'org.projectlombok:lombok:1.18.22'
  testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
}
Delombok
Lombok tarafından üretilen kodu görmeyi sağlar. IDE'ler delombok için menü sağlıyorlar. Şeklen şöyle. Burada 
1. Tüm anotasyonlar veya 
2. Sadece class içindeki bazı anotasyonları kapatabiliriz.



Lombok Anotasyonları
Açıklaması şöyle
Val - Creates a local variable with val which will be initialized based on initialization expression. The local variable will also be made final.
Var - Works exactly like Val but the local variable is not declared final.
@Setter - Add setter for all variables.
@Getter -  Add getter for all the variables.
@RequiredArgsConstructor - Generates constructor for each field.
@NoArgsConstructor - Creates a non-parametrized constructor.
@AllArgsConstructor - Creates a parametrized constructor containing all fields.
@ToString - Creates toString method.
@EqualsAndHashCode - Creates Equals and Hashcode implementation for fields in the class.

@Data - It is a quick way of combining features of @ToString, @EqualsAndHashCode, @Getter@Setter and @RequiredArgsConstructor
@Builder - Makes instantiation of class easier and provides a way to statically initialize fields in a class.
@Cleanup yazısına bakabilirsiniz.
@Log yazısına bakabilirsiniz.
@NonNull yazısına bakabilirsiniz.
@Slf4j yazısına bakabilirsiniz.
@SneakyThrows yazısına bakabilirsiniz
@Synchronized yazısına bakabilirsiniz
@UtilityClass yazısına bakabilirsiniz.
@Value yazısına bakabilirsiniz
@With yazısına bakabilirsiniz

5 Ocak 2021 Salı

Lombok @SneakyThrows Anotasyonu

Giriş
Checked exception'ları RuntimeException ile sarmalar. Açıklaması şöyle
A common critique of Java is the verbosity created by throwing checked exceptions. Lombok has an annotation to remove the need for those pesky throws keywords: @SneakyThrows. As you might expect, the implementation is quite sneaky. It does not swallow or even wrap exceptions into a RuntimeException. Instead, it relies on the fact that at runtime, the JVM does not check for the consistency of checked exceptions. Only javac does this. So Lombok uses bytecode transformations to opt out of this check at compile time.
Üretilen Kod
Şuna benzer
@SuppressWarnings("unchecked")
static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
  throw (T) t;
}

static void testSneaky() {
  final Exception e = new Exception();
  sneakyThrow(e);    // No Errors
}
Neden Çalışıyor
Language specification section 18.4 için açıklama şöyle
… Otherwise, if the bound set contains throws αi, and the proper upper bounds of αi are, at most, Exception, Throwable, and Object, then Ti = RuntimeException
Bu şu anlama gelir. T tipi Throwable olarak tanımlandığı için RuntimeException olarak anlamlandırılıyor.
This exact case applies to sneakyThrows, It states that if the type’s only upper bound is almost Exception, Throwable, and Object, then T will be inferred to be a RuntimeException as per the specification, so it compiles.
Örnek
Şöyle yaparız. Burada checked exception olan Exception, RuntimeException ile sarmalanıyor
public class SneakyThrows {
@SneakyThrows public void sneakyThrow() { throw new Exception(); } }
Örnek
Şöyle yaparız. Burada  checked exception olan ParseException, RuntimeException ile sarmalanıyor
@SneakyThrows
public static Date parseDate(String dateStr) {
  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
  return format.parse(dateStr);
}
Aslında kodu şu hale getiriyor
public static Date parseDate(String dateStr) {
  try {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    return format.parse(dateStr);
  } catch (ParseException e) {
    throw new RuntimeException(e); 
  }
}
value Alanı
Fırlatılmasını istediğimiz exception belirtilebilir.

Örnek
Şöyle yaparız. Burada kod IOException fırlatıyor. Biz de yine aynısı fırlatılsın istiyoruz ama metod imzasında bu exception kullanılsın istemiyoruz.
@SneakyThrows(IOException.class)
void throwException(String a) {
  ...
  throw new IOException();
}

23 Haziran 2020 Salı

Lombok @Builder Anotasyonu - Nesneyi Builder Şeklinde Kurabilmemizi Sağlar

Giriş
Şu satırı dahil ederiz
import lombok.Builder;
Sınıfa @Builder anotasyonu eklenir daha sonra Foo.builder().field1().field2().build() şeklinde kullanılır. Setter olarak setField1() değil field1() şeklinde metodlar sağlıyor.

Örnek
Elimizde şöyle bir kod olsun.
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
public class Customer {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String firstName;
  private String lastName;
  private String birthdate;
}
Şöyle kullanabiliriz.
public Customer mapFieldSet(FieldSet fieldSet) throws BindException {
    return Customer.builder()
      .id(fieldSet.readLong("id"))
      .firstName(fieldSet.readRawString("firstName"))
      .lastName(fieldSet.readRawString("lastName"))
      .birthdate(fieldSet.readRawString("birthdate"))
      .build();
  }
Varsayılan Değerler Nasıl Yapılır
Örnek
Şöyle yaparız. Burada varsayılan değerler veriliyor. Bu varsayılan değerler sadece Builder.build() kullanımında işe yarıyor.
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class WebClientComposer {

  static final boolean DEFAULT_SOCKET_KEEP_ALIVE_ENABLED = true;
  static final boolean DEFAULT_HTTP_PROXY_ENABLED = false;
  static final int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 5000;
  static final int MAX_IN_MEMORY_SIZE_BYTES = 1024 * 1024;

  @Builder.Default
  private final String baseUrl = "";
  @Builder.Default
  private final int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT_MILLIS;
  @Builder.Default
  private final int readTimeoutSecs = 0;
  @Builder.Default
  private final boolean socketKeepAlive = DEFAULT_SOCKET_KEEP_ALIVE_ENABLED;
  @Builder.Default
  private final int maxInMemorySize = MAX_IN_MEMORY_SIZE_BYTES;
  @Builder.Default
  private final int maxPoolConnectionSize = ...;
  ...
}
Mecburi Alan (Mandatory Field) Nasıl Yapılır
Örnek
Şöyle yaparız. Burada mecburi alan lombok.NonNull ile işaretli. Ayrıca Lombok builde döndürent metodun ismini de belirtiyoruz ve kullanıyoruz
@Data @Builder(builderMethodName = "internalBuilder") static class Student { @NonNull private String firstName; private String lastName; private String studentId; private Integer year; private List<Integer> marks; public static StudentBuilder builder(String name) { return internalBuilder().firstName(name); } }
Calculate The Value of a Field Based On Another Mandatory Field
Örnek
Şöyle yaparız
@Data public class Student { @NonNull private String firstName; private String lastName; private String studentId; private Integer year; private List<Integer> marks; public static StudentBuilder builder(String name) { return internalBuilder().firstName(name); } @Builder(builderMethodName = "internalBuilder") private Student(String firstName, String lastName, List<Integer> marks, Integer year) { this.firstName = firstName; this.lastName = lastName; this.marks = marks; this.year = year; //generate some value based on other fields this.studentId = generateStudentId(firstName); } private String generateStudentId(String firstName) { return firstName + new Random().nextInt(1000); } }
Ancak bu kullanımı anlamak zor. Bunun yerine Fluent Setters kullanılabilir. Şöyle yaparız
@Data @Accessors(chain = true, fluent = true) public class Student { private String firstName; private String lastName; private String studentId; private Integer year; private List<Integer> marks; public Student(@NonNull String firstName) { this.firstName = firstName; this.studentId = generateStudentId(firstName); } private String generateStudentId(String firstName) { return firstName + new Random().nextInt(1000); } } Student student = new Student("John").lastName("Doe").year(2);

Anotasyonun Alanları

builderClassName Alanı
Örnek - Varsayılan Değeler
Şöyle yaparız
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder") method(String a, String b, String c) { ... acutal logic here ... } private class MethodBuilder { private String a = "Hello"; private String b = "builder"; private String c = "world!"; }
buildMethodName  Alanı
Lombok tarafından üretilecek metod ismini belirtir. Böylece gerekirse bu metod çağırmak istersek ismini bilebiliriz.
Örnek
Şöyle yaparız
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call") void method(@NotNull String firstParam, @NotNull String secondParam, String thirdParam, String fourthParam, Long fifthParam, @NotNull Object sixthParam) { ... } methodBuilder() .firstParam("A") .secondParam("B") .sixthParam(new Object()) .call(); methodBuilder() .firstParam("A") .secondParam("B") .thirdParam("C") .fifthParam(2L) .sixthParam("D") .call(); methodBuilder() .firstParam("A") .secondParam("B") .fifthParam(3L) .sixthParam(this)         .call();
Örnek - Generic Code
Şöyle yaparız
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder") public <T extends Collection> T read(final byte[] content, final Class<T> type) {...} public <T extends Collection> MethodBuilder<T> methodBuilder(final Class<T> type) { return new MethodBuilder<T>().type(type); } public class MethodBuilder<T extends Collection> { private Class<T> type; public MethodBuilder<T> type(Class<T> type) { this.type = type; return this; } public T call() { return read(content, type); } }
veya şöyle yaparız
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder") public <T extends Collection> T read(final byte[] content, final Class<T> type) {...} public class MethodBuilder<T extends Collection> { private Class<T> type; public <L extends Collection> MethodBuilder<L> type(final Class<L> type) { this.type = (Class)type; return (MethodBuilder<L>) this; } public T call() { return read(content, type); } }

toBuilder Alanı
Nesneyi kurmak için builder() metodu yanında, nesnenin kopyasını almak için toBuilder() metodu sağlar.
Örnek - true Verirsek Clone Yapılabilir
Açıklaması şöyle
Finally, the toBuilder = true setting adds an instance method toBuilder() that creates a builder object populated with all the values of that instance. This enables an easy way to create a new instance prepopulated with all the values from the original instance and change just the fields needed. This is particularly useful for @Value classes because the fields are immutable.
Şöyle yaparız
@Builder(toBuilder=true)
class Foo {
   int x;
   ...
}

Foo f0 = Foo.builder().build();
Foo f1 = f0.toBuilder().x(42).build();

11 Aralık 2019 Çarşamba

Lombok @RequiredArgsConstructor Anotasyonu

Giriş
Şu satırı dahil ederiz.
import lombok.RequiredArgsConstructor;
Açıklaması şöyle.
The @RequiredArgsConstructor annotation in Java Lombok is used to automatically generate a constructor for a class that initializes all final fields, as well as any non-final fields with the @NonNull annotation.
1. Alanlar final olabilir.
2. Alanlar @lombok.NonNull olarak işaretli olabilir.

Örnek
Şöyle yaparız.
@RequiredArgsConstructor
public class Fooo {
  ...
}
Örnek
Şöyle yaparız.
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor

public class HelloResponseDto {
    private final String name;
    private final int amount;
}