티스토리 뷰

롬복 아이콘

학습목표

  • 롬복이란
  • 롬복의 원리
  • 설치
  • 롬복 기능 설명

롬복 도큐먼테이션 정리 1부이다. 도큐먼트 순서대로 업데이트할 예정이다.


롬복이란?

롬복은 편집기에 자동으로 연결되고, 도구를 빌드해 java 를 멋지게 꾸미는 java 라이브러리입니다. 다른 getter 또는 setter, equals 메소드를 다시 작성하지 마세요. 하나의 주석을 이용해 완전한 기능의 빌더가 있고, 로깅 변수를 자동화 하는 등의 작업을 수행할 수 있습니다.

라는 것이 공식페이지 의 설명이다. 즉, 자바의 보일러 플레이트 코드(라 쓰고 상용구라 읽는다. ) 를 생성하는 자동화 작업을 수행함으로써 보일러 플레이트 코드를 제거할 수 있다. 알면 알수록 아주 효율적이라는 이야기이다! 그러니 진지하게 각. 잡고 이 블로그를 읽어주었으면 좋겠다.

자바 언어에 대한 가장 빈번한 비판 중 하나는 코드의 양이다. 이 문제는 종종 다양한 라이브러리의 디자인 결정의 결과이지만 언어 자체의 제한으로 인해 악화된다. Lombok은 일부 최악의 범죄자를 간단한 주석 세트로 대체하여 발암률을 줄이는 것을 목표로한다.

IDE에 통합함으로써 Project Lombok은 개발자가 즉시 사용할 수있는 코드를 삽입 할 수 있다.

롬복의 원리

Lombokjava source를 컴파일 할 때, annotation processor로 등록된 lombok processorannotation을 확인 후, 그에 맞는 메소드를 자동으로 생성해 바이트 코드로 변환하는 방식을 사용한다.

즉, Lombok은 컴파일 시간에만 작동하기 때문에, pom 파일에 런타임 종속성으로 두는 것은 의미가 없다. 따라서 검증, 운영 배포 할 때는 배제해야 한다.


설치

1. intellij lombok 플러그인 설치

2. maven 의존관계 설정

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

🎁 깨알 팁: optional 태그의 경우, 이 프로젝트가 다른 프로젝트에 의존성을 가진 경우, 사용할지 여부를 선택해준다.
예를 들어, A라는 프로젝트에서 B아는 프로젝트를 참조해 사용할 때, B 의 dependency elementoptionaltrue로 주는 경우, A프로젝트에서는 해당 라이브러리를 참조하지 않게 된다. 즉, 의존성 정보를 다른 프로젝트에 전달하고 싶지 않을 때 사용하는 속성이다.

 <build>
         <plugins>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <configuration>
                     <excludes>
                         <exclude>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                         </exclude>
                     </excludes>
                 </configuration>
             </plugin>
         </plugins>
  </build>

롬복 기능

val

Hassle-free final local variables. 즉, 최종 지역 변수. 수정이 불가능하다. 코틀린 문법의 val 과 유사하다 생각하면 된다.

  • 초기화될때 유형이 유추된다.
  • 또한 자동으로 final 로 인식된다.
  • 이 기능은 지역변수와 foreach루프에서만 작동되고 필드에서 작동하지 않는다.
  • *경고 :이 기능은 현재 NetBeans에서 작동하지 않는다.
  • 예시 코드
import java.util.ArrayList;  
import java.util.HashMap;  
import lombok.val;

public class ValExample {  
public String example() {  
val example = new ArrayList(); // same as final ArrayList example = 블라블라블라  
example.add("Hello, World!");  
val foo = example.get(0); // final String foo =블라블라블라  
return foo.toLowerCase();  
}

public void example2() {  
val map = new HashMap<Integer, String>(); // final HashMap<Integer, String> map =블라블라블라  
map.put(0, "zero");  
map.put(5, "five");  
for (val entry : map.entrySet()) {// final Map.Entry<Integer, String> entry : 블라블라블라  
System.out.printf("%d: %s\\n", entry.getKey(), entry.getValue());  
}  
}  
}
  • 초기화 표현식이 null인 경우와 같이 모호한 경우 java.lang.Object가 유추된다.
  • 복합 유형의 경우 공유 인터페이스가 아닌 가장 일반적인 수퍼 클래스가 유추된다.
  • Lombok은 val구성된 경우 의 모든 사용을 경고 또는 오류로 표시할 수 있다. 이것에 대한 설정은 lombok.val.flagUsage= [ warning| error] (기본값 : 설정되지 않음) 여기서 파악하면 된다.

var

변거롭지 않은 지역 변수. 수정이 가능하다. 코틀린 문법의 var 과 유사하다 생각하면 된다.

  • 초기화될때 유형이 유추된다.
  • 변수의 값을 수정할 수 있다.(final 표기 NO)
  • 이 기능은 지역변수와 foreach루프에서만 작동되고 필드에서 작동하지 않는다. (val 과 유사)
  • 유형은 초기 표현식에서 완전히 결정되기 때문에, 후에 추가 할당에서 다른 유형으로 변환 시도시, 에러가 발생한다.Lombok은 var구성된 경우 의 모든 사용을 경고 또는 오류로 표시할 수 있다. 이것에 대한 설정은 lombok.var.flagUsage= [ warning| error] (기본값 : 설정되지 않음) 여기서 파악하면 된다.
  • var x = "Hello"; // 이미 String으로 인식돼어 아래 문장 실행시, 유형 에러가 발생한다. x = Color.RED //java.lang.Object된 경우이 코드는 컴파일되었을 수 있지만 var작동 방식은 그렇지 않다.

@NonNull

  • 필드 값이 없으면, NullPointerException 을 일으킨다.
  • @NonNull메소드 또는 생성자의 매개 변수를 사용 하여 lombok이 널 검사 명령문을 생성하도록 할 수 있다.
  • null check는 if (param == null) throw new NullPointerException("param is marked @NonNull but is null")와 같은 방법으로 맨 위에 삽입 된다.
  • 생성자의 경우 명시적으로 this() 또는 super() 호출 직후에 null 검사가 시작된다.
  • null 검사가 상위에 있는 경우, 추가 null 검사를 실행하지 않는다.
import lombok.NonNull;

public class NonNullExample extends Something {  
private String name;

public NonNullExample(@NonNull Person person) {  
/*  
same as  
if (person == null) {  
throw new NullPointerException("person is marked @NonNull but is null");  
}  
*/  
super("Hello");  
this.name = person.getName();  
}  
}
  • 에러 타입을 변경할 수 있다.

lombok.nonNull.exceptionType= [ NullPointerException| IllegalArgumentException| JDK| Guava| Assertion] (기본값 :) NullPointerException.

  • JDK또는 Guava결과는 다음 두 프레임 워크의 표준 nullcheck 메서드 java.util.Objects.requireNonNull([field name here], "[field name here] is marked non-null but is null");또는 com.google.common.base.Preconditions.checkNotNull([field name here], "[field name here] is marked non-null but is null");각각 에 대한 호출을 발생시킨다.
  • @NonNull 구성시 경고, 오류 표기

lombok.nonNull.flagUsage= [ warning| error] (기본값 : 설정되지 않음)


@Cleanup

  • 자동 리소스 관리: close() 라는 자원 리소스 닫는 번거로움 없이 안전하게 메소드를 호출할 수 있다.
  • @Cleanup하여 코드 실행 경로가 현재 범위를 벗어나기 전에 지정된 리소스가 자동으로 정리되도록 할 수 있다 .
  • @Cleanup InputStream in = new FileInputStream("some/file");
  • 결과적으로 현재 범위의 끝에서 in.close()호출된다. 이 호출은 try / finally구성을 통해 실행된다.
  • 정리하려는 객체 유형에 close()메서드가 없지만 인수가없는 다른 메서드가있는 경우 다음과 같이이 메서드의 이름을 지정할 수 있다.
  • @Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
    기본적으로 정리 메서드는 close(). 하나 이상의 인수를 사용하는 정리 메서드는 @Cleanup를 통해 호출 할 수 없다.
import lombok.Cleanup;  
import java.io.\*;

public class CleanupExample {  
public static void main(String\[\] args) throws IOException {  
@Cleanup InputStream in = new FileInputStream(args\[0\]);  
@Cleanup OutputStream out = new FileOutputStream(args\[1\]);  
byte\[\] b = new byte\[10000\];  
while (true) {  
int r = in.read(b);  
if (r == -1) break;  
out.write(b, 0, r);  
}  
}  
}  
/*

import java.io.*;

public class CleanupExample {  
public static void main(String\[\] args) throws IOException {  
InputStream in = new FileInputStream(args\[0\]);  
try {  
OutputStream out = new FileOutputStream(args\[1\]);  
try {  
byte\[\] b = new byte\[10000\];  
while (true) {  
int r = in.read(b);  
if (r == -1) break;  
out.write(b, 0, r);  
}  
} finally {  
if (out != null) {  
out.close();  
}  
}  
} finally {  
if (in != null) {  
in.close();  
}  
}  
}  
}  
*/
  • lombok.cleanup.flagUsage= [ warning| error] (기본값 : 설정되지 않음) // 모든 사용을 경고 또는 오류로 표시

@Getter 와 @Setter

  • 기본 getter / setter를 자동으로 생성하도록하려면 모든 필드에 @Getter / @Setter을 달 수 있다. .
    기본 getter는 단순히 필드를 반환하고 필드 setFoo가 호출되면 이름이 지정 된다.

  • 명명규칙: 메소드 이름을 생성하기 위해 필드의 첫 번째 문자가 소문자 인 경우 대문자로 표시되고 그렇지 않으면 수정되지 않은 상태로 유지된다. 그런 다음 get / set / is 접두사가 붙는다.

  • 리턴타입이 java.lang.Boolean 인 경우, get접두사가 아닌 is접두사가 된다.

  • 예시

  • import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class GetterSetterExample { @Getter @Setter private int age = 10; @Setter(AccessLevel.PROTECTED) private String name; @Override public String toString() { return String.format("%s (age: %d)", name, age); } }

  • 접근 제한자 : 생성되는 getter/setter에 명시적으로 AccessLevel을 명시해주지 않으면, 접근 제한자는 public이 된다.

    • @Setter(AccessLevel.PROTECTED) 처럼 PUBLIC, PROTECTED, PACKAGE, PRIVATE 로 AccessLevel 을 지정 가능하다.
  • 객체유형별 getter, setter

    • 클래스에 붙인다면, static이 아닌 전체 필드에 @Getter@Setter애노테이션이 적용된다. (@Data)
      • 만약 특정 필드에서 @Getter, @Setter의 생성을 막고 싶다면 AccessLevel.None을 사용할 수 있다. AccessLevel.None으로 값을 설정하면 해당 필드는 lombok이 메소드를 생성하지 않는다.
    • 열거형 Enum에도 @Getter를 사용할 수 있다. 하지만 @Setter는 사용할 수 없다.
  • 커스텀

    • @Accessors(chain = true) : chain 옵션은 사용할 경우에는 setter가 만들어 질 때 해당 클래스를 다시 리턴하는 체이닝방식으로 만들어진다. (@Accessors: getter 및 setter를위한 속성 지원 API)

      • @Accessors(chain = true)
        @Data
        public class AccessorsExample {
        
            private String name;
            private String email;
        }
      • AccessorsExample emailAccessors = accessorsExample.email("a@test.com");

    • @Accessor(fluent = true) 를 적용하면, set, get 없이 프로퍼티 이름으로 쓸수 있다.

    • 예시

      • @Accessors(fluent = true)
        @Data
        public class AccessorsExample {
        
            private String name;
            private String email;
        }

        AccessorsExample emailAccessors = accessorsExample.email("a@test.com");

      • get과 set이 라는 prefix가 사라지고 email, name 으로 상태를 변경 시키고, 값을 가져올 수 있다.

      • 상태만 변경시키지 새로운 Object을 만드는 것은 아니다.

    • @Accessors(prefix = "m") 같은 설정으로 접두사를 제거 가능하다.(추가도 가능한 것으로 추정됨. )

      • 예시: 아래 코드는 getMNum() 대신 getNum() 형식의 getter를 만든다.
      • @Accessors(prefix = "m")
        public class MyClass {
            @Getter private int mNum;
        }
  • lombok.copyableAnnotations= [ 정규화 된 유형 목록 ] (기본값 : 빈 목록)
    • Lombok은 이러한 주석을 필드에서 setter 매개 변수와 getter 메소드로 복사합니다. lombok에는 복사 가능한 것으로 알려진 '즉시 사용 가능한'주석이 함께 제공됩니다. 모든 인기있는 nullable / nonnull 주석입니다. ( 읽어도 모르겠고, 구글링도 모르겠다. 후에 필요할 때 다시 공부하는 것으로..)
  • 여러 주석을 동시에 이용 가능하다.
  • 에러 , 경고 표기
  • lombok.setter.flagUsage= [ warning| error] (기본값 : 설정되지 않음) lombok.getter.flagUsage= [ warning| error] (기본값 : 설정되지 않음)
  • 동일한 이름 (대소 문자 구분 안 함) 및 동일한 매개 변수 수를 가진 메소드가 이미 존재하는 경우 메소드가 생성되지 않는다.

@ToString

toString() 메소드를 롬복에서 자동으로 구현해준다. 기본적으로 클래스명과 각각의 필드를 ,로 구분해서 설명한다.

  • 기본: 모든 non-static 필드..
  • 제외하고 싶은 필드는 @ToString.Exclude 를 활용해 제거가능하다.
  • 명시적으로 추가하고 싶은 경우 @ToString(onlyExplicitlyIncluded = true), @ToString.Include를 이용한다.
  • callSuper 을 true 로 지정함으로써 슈퍼클래스의 toString 의 구현 또한 추가할 수 있다.

@EqualsAndHashCode

개체의 hashCode와 equals 를 구현한다.

  • equals(Object other)hashCode()메서드의 구현을 생성 할 수 있도록 모든 클래스 정의에 주석을 달 수 있다.

  • 기본적으로 모든 비 정적, 비 일시적 필드를 사용하지만 유형 멤버를 @EqualsAndHashCode.Include또는 @EqualsAndHashCode.Exclude으로 표시하여 사용되는 필드를 수정할 수 있으며 다양한 메서드의 출력이 사용되도록 지정할 수도 있다


@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

생성자를 자동으로 생성해주는 어노테이션들: 인수 없는 생성자, 최종, NonNull필드들에 대한 생성자, 모든 필드에 대해 하나의 인수를 사용하는 생성자''

  • 이 3개의 주석 세트는 특정 필드에 대해 1개의 매개 변수를 허용하는 생성자를 생성하고 단순히 매개변수를 필드에 할당한다.

@NoArgsConstructor

  • 파라미터 없는 생성자를 생성한다.

  • 필드들이 final로 생성되어있는 경우에 필드를 초기화할 수 없기 때문에 생성자를 만들 수 없고 에러가 발생하게 된다

  • @NoArgsConstructor(force = true) : 모든 final 필드가 0, false, null 으로 강제 초기화시켜 생성자를 만들 수 있다.

  • @NonNull 과 같이 필드에 제약조건이 설정된 경우, 생성자 내 null-check 로직이 생성되지 않는다.

  • (후에 초기화를 진행하기 전까지 null-check 로직이 발생하지 않는다는 점을 염두에 두고 개발해야한다.)

@RequiredArgsCosntructor

이 어노테이션은 추가 작업을 필요로 하는 필드에 대한 생성자를 생성하는 어노테이션이다.

초기화되지 않은 모든 final 필드, @NonNull 필드에 대해 생성자들을 자동으로 생성해준다.

  • @NonNull 로 마크되어있는 필드들은 null-check 가 추가적으로 발생되고, @NonNull 이 마크되어있지만, 파라미터에서 null 값이 들어온다면 생성자에서 NullPointerException이 발생한다.
  • 매개변수의 순서는 클래스에 필드가 나타나는 순서와 일치한다.

@AllArgsConstructor

이 어노테이션은 클래스에 존재하는 모든 필드에 대해 생성자를 자동으로 생성해준다.

@NonNull 로 표기된 매개변수에 대해 널 검사를 수행한다.

생성자 관련 어노테이션을 사용할 때 주의사항

  • static 필드들은 skip된다.
  • 파라미터의 순서는 클래스 명시 순서에 따라 생성하기 때문에 주의를 기울여야한다.
  • accessLievel을 꼭 설정해줘야한다.
  • 기본값은 public 이지만, 필요에 따라 접근 제한자를 설정해줘야한다.
  • 자세한 설명은 (여기)[https://kwonnam.pe.kr/wiki/java/lombok/pitfall]를 참고하면 좋다.

staticName 옵션을 이용한 static factory 메소드 생성

@RequiredArgsConstructor(staticName = "of”)

위의 3개의 생성자 관련 어노테이션은 static factory를 만들 수 있는 옵션이 있다.

staticName이라는 옵션을 이용해 생성자를 private로 생성하고, private 생성자를 감싸고 있는 static factory 메소드를 추가할 수 있다.


참고 문헌

https://projectlombok.org/
https://projectlombok.org/features/GetterSetter
https://dingue.tistory.com/14
http://wonwoo.ml/index.php/post/category/uncategorized
https://gist.github.com/ihoneymon/8b62cabb2e985c4ebd29271b3e25181f ( 롬복 사용시, Qualifier 어노테이션 적용 안됨.)
https://projectlombok.org/features/GetterSetter
https://dingue.tistory.com/14
https://projectlombok.org/
롬복사용시주의점

'스프링, 자바' 카테고리의 다른 글

Log4j 레벨 간단 정리  (0) 2021.03.29
Dispatcher-Servlet  (0) 2021.03.04
Lombok 도큐먼트 정리  (0) 2021.03.04
[자바]HashMap과 HashTable의 차이점  (0) 2021.02.26
자바의 단점 , 보일러 플레이트  (0) 2021.02.25
java Reflection  (0) 2021.02.22
TAG
댓글
댓글쓰기 폼