자바 Lombok 소개,사용,작업 원리,장단 점

18904 단어 JavaLombok
간단 한 소개
공식 소개
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again, with one annotation your class has a fully featured builder, automate your logging variables, and much more.
번역 후:
Lombok 프로젝트 는 자바 라 이브 러 리 입 니 다.편집기 와 구축 도구 에 자동 으로 삽입 되 어 자바 를 간소화 합 니 다.다른 getter,setter,toString 또는 equals 방법 을 쓸 필요 가 없습니다.설명 이 있 는 클래스 는 전면적 인 생 성 기 를 가지 고 있 습 니 다.로그 기록 변 수 를 자동화 하고 더 많은 기능 을 사용 할 수 있 습 니 다.
홈 페이지 링크
쓰다
maven 의존 도 추가

<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.16</version>
 <scope>provided</scope>
</dependency>
주의:여기scope에서provided로 설정 하여 다른 항목 에 의존 하지 않도록 해 야 합 니 다.
플러그 인 설치(선택 가능)
개발 과정 에서 일반적으로 플러그 인 에 맞 춰 사용 해 야 하 며,IDEA 에 Lombok 플러그 인 을 설치 하면 됩 니 다.
플러그 인 을 왜 설치 합 니까?
우선 플러그 인 을 설치 하지 않 은 상태 에서 코드 는 정상적으로 컴 파일 되 고 실 행 될 수 있 습 니 다.플러그 인 을 설치 하지 않 으 면 IDEA 는 Lombok 이 컴 파일 할 때 만 생 성 되 는 모델 링 방법 을 자동 으로 알려 주지 않 습 니 다.마찬가지 로 IDEA 는 문법 정확성 을 검증 할 때 도 문제 가 있 음 을 알려 주 고 큰 면적 으로 빨간색 을 보고 하 는 코드 가 있 습 니 다.
예시
밤 두 개 를 들 어 lombok 사용 과 사용 하지 않 는 차이 점 을 살 펴 보 자.
사용자 클래스 만 들 기
Lombok 사용 안 함

public class User {
 private Integer id;
 private Integer age;
 private String realName;

 public User() {
 }

 @Override
 public boolean equals(Object o) {
 if (this == o) {
  return true;
 }
 if (o == null || getClass() != o.getClass()) {
  return false;
 }

 User user = (User) o;

 if (!Objects.equals(id, user.id)) {
  return false;
 }
 if (!Objects.equals(age, user.age)) {
  return false;
 }
 return Objects.equals(realName, user.realName);
 }

 @Override
 public int hashCode() {
 int result = id != null ? id.hashCode() : 0;
 result = 31 * result + (age != null ? age.hashCode() : 0);
 result = 31 * result + (realName != null ? realName.hashCode() : 0);
 return result;
 }

 @Override
 public String toString() {
 return "User{" +
  "id=" + id +
  ", age=" + age +
  ", realName='" + realName + '\'' +
  '}';
 }

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 public Integer getAge() {
 return age;
 }

 public void setAge(Integer age) {
 this.age = age;
 }

 public String getRealName() {
 return realName;
 }

 public void setRealName(String realName) {
 this.realName = realName;
 }
}
Lombok 사용 하기

@Data
public class User {
 private Integer id;
 private String username;
 private Integer age;
}
@Data 주 해 를 사용 하면 컴 파일 할 때 다음 템 플 릿 코드 가 자동 으로 생 성 됩 니 다.
  • toString
  • equals
  • hashCode
  • getter 는 final 속성 에 생 성 되 지 않 습 니 다
  • setter 는 final 속성 에 생 성 되 지 않 습 니 다
  • 필요 한 매개 변수의 구조 기
  • 필요 한 매개 변수 가 무엇 인지 예 를 들 어 설명 하 겠 습 니 다.
    모든 주석
    위 에@Data 주 해 를 간단하게 보 았 고,아래 에 쓸 수 있 는 모든 주 해 를 보 았 다.
    @NonNull 은 필드 와 구조 기의 인자 에 주석 을 달 았 습 니 다.주 해 는 필드 에 setter,constructor 방법 에 빈 칸 을 추가 합 니 다.@Setter,@RequiredArgs Constructor,@AllArgs Constructor 에 맞 춰 사용 해 야 합 니 다.주 해 는 구조 기 방법 파라미터 에 있어 서 구조 할 때 판 공 을 넣는다.
    @Cleanup 주 해 는 로 컬 변수 에 있 습 니 다.자원 청 소 를 책임 지고 방법 이 직접 끝 날 때 close 방법 을 호출 합 니 다.
    @Setter 주 해 는 클래스 나 필드 에 있 습 니 다.주 해 는 클래스 에 있 을 때 모든 필드 에 setter 방법 을 생 성 합 니 다.주 해 는 필드 에 있 을 때 이 필드 에 만 setter 방법 을 생 성 하 는 동시에 생 성 된 setter 방법의 접근 단 계 를 지정 할 수 있 습 니 다.
    @Getter 사용 방법 은@Setter 와 같 습 니 다.다른 것 은 getter 방법 을 생 성 하 는 것 입 니 다.
    @ToString 주 해 는 클래스 에 있 습 니 다.toString 방법 추가
    @EqualsAndHashCode 주 해 는 클래스 에 있 습 니 다.hashCode 와 equals 생 성 방법
    @NoArgs Constructor 주 해 는 클래스 에 있 습 니 다.무 삼 을 만 드 는 구조 방법.
    @RequiredArgs Constructor 주 해 는 클래스 에 있 습 니 다.클래스 에서 특수 처리 가 필요 한 필드 생 성 구조 방법,예 를 들 어 final 과@NonNull 에 의 해 주 해 된 필드.
    @AllArgs Constructor 는 클래스 에 주석 을 달 고 클래스 의 모든 필드 를 포함 하 는 구조 방법 을 생 성 합 니 다.
    @Data 주 해 는 클래스 에서 setter/getter,equals,canEqual,hashCode,toString 방법 을 생 성 합 니 다.final 속성 이 라면 이 속성 에 setter 방법 을 생 성하 지 않 습 니 다.
    @Value 주 해 는 클래스 와 속성 에 있 습 니 다.클래스 에서 클래스 인 스 턴 스 를 만 든 후 수정 할 수 없습니다.setter 방법 이 생 성 되 지 않 으 면@Setter 가 작 동 하지 않 습 니 다.
    @Builder 주 해 는 클래스 에서 구조 기 를 생 성 합 니 다.
    @SneakyThrows
    @Synchronized 주석 방법 에 동기 화 방법 생 성
    @With
    로그 관련:클래스 에 주석 을 달 고 log 상수 생 성,private static final xxx log 와 유사 합 니 다.
  • @Log java.util.logging.Logger
  • @CommonsLog org.apache.commons.logging.Log
  • @Flogger com.google.common.flogger.FluentLogger
  • @JBossLog org.jboss.logging.Logger
  • @Log4j org.apache.log4j.Logger
  • @Log4j2 org.apache.logging.log4j.Logger
  • @Slf4j org.slf4j.Logger
  • @XSlf4j org.slf4j.ext.XLogger
  • 모든 주석 을 볼 수 있 습 니 다https://projectlombok.org/features/all
    종합 실례
    종합 실례 1
    
    import lombok.AccessLevel;
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.EqualsAndHashCode;
    import lombok.Getter;
    import lombok.NonNull;
    import lombok.RequiredArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    
    @Getter      //    getter
    @AllArgsConstructor   //        
    @RequiredArgsConstructor //           
    @ToString   //    toString
    @EqualsAndHashCode //    equals   hashCode
    @Builder   //      builder
    public class UserLombok {
    
     //    setter      id     
     @Setter
     @NonNull
     private Integer id;
    
     //    setter             PROTECTED
     @Setter(AccessLevel.PROTECTED)
     private Integer age;
    
     //    setter        
     @Setter
     private String realName;
    
     //    ,   id     
     public UserLombok(@NonNull Integer id, Integer age) {
     this.id = id;
     this.age = age;
     }
    
     /**
     *     realName   setter   ,       Lombok
     * @param realName     
     */
     public void setRealName(String realName) {
     this.realName = "realName:" + realName;
     }
    }
    구체 적 으로 생 성 된 종 류 는?
    
    import lombok.NonNull;
    
    public class UserLombok {
     @NonNull
     private Integer id;
     private Integer age;
     private String realName;
    
     public UserLombok(@NonNull Integer id, Integer age) {
     if (id == null) {
      throw new NullPointerException("id is marked non-null but is null");
     } else {
      this.id = id;
      this.age = age;
     }
     }
    
     public void setRealName(String realName) {
     this.realName = "realName:" + realName;
     }
    
     public static UserLombok.UserLombokBuilder builder() {
     return new UserLombok.UserLombokBuilder();
     }
    
     @NonNull
     public Integer getId() {
     return this.id;
     }
    
     public Integer getAge() {
     return this.age;
     }
    
     public String getRealName() {
     return this.realName;
     }
    
     public UserLombok(@NonNull Integer id, Integer age, String realName) {
     if (id == null) {
      throw new NullPointerException("id is marked non-null but is null");
     } else {
      this.id = id;
      this.age = age;
      this.realName = realName;
     }
     }
    
     public UserLombok(@NonNull Integer id) {
     if (id == null) {
      throw new NullPointerException("id is marked non-null but is null");
     } else {
      this.id = id;
     }
     }
    
     public String toString() {
     return "UserLombok(id=" + this.getId() + ", age=" + this.getAge() + ", realName=" + this.getRealName() + ")";
     }
    
     public boolean equals(Object o) {
     if (o == this) {
      return true;
     } else if (!(o instanceof UserLombok)) {
      return false;
     } else {
      UserLombok other = (UserLombok)o;
      if (!other.canEqual(this)) {
      return false;
      } else {
      label47: {
       Object this$id = this.getId();
       Object other$id = other.getId();
       if (this$id == null) {
       if (other$id == null) {
        break label47;
       }
       } else if (this$id.equals(other$id)) {
       break label47;
       }
    
       return false;
      }
    
      Object this$age = this.getAge();
      Object other$age = other.getAge();
      if (this$age == null) {
       if (other$age != null) {
       return false;
       }
      } else if (!this$age.equals(other$age)) {
       return false;
      }
    
      Object this$realName = this.getRealName();
      Object other$realName = other.getRealName();
      if (this$realName == null) {
       if (other$realName != null) {
       return false;
       }
      } else if (!this$realName.equals(other$realName)) {
       return false;
      }
    
      return true;
      }
     }
     }
    
     protected boolean canEqual(Object other) {
     return other instanceof UserLombok;
     }
    
     public int hashCode() {
     int PRIME = true;
     int result = 1;
     Object $id = this.getId();
     int result = result * 59 + ($id == null ? 43 : $id.hashCode());
     Object $age = this.getAge();
     result = result * 59 + ($age == null ? 43 : $age.hashCode());
     Object $realName = this.getRealName();
     result = result * 59 + ($realName == null ? 43 : $realName.hashCode());
     return result;
     }
    
     public void setId(@NonNull Integer id) {
     if (id == null) {
      throw new NullPointerException("id is marked non-null but is null");
     } else {
      this.id = id;
     }
     }
    
     protected void setAge(Integer age) {
     this.age = age;
     }
    
     public static class UserLombokBuilder {
     private Integer id;
     private Integer age;
     private String realName;
    
     UserLombokBuilder() {
     }
    
     public UserLombok.UserLombokBuilder id(@NonNull Integer id) {
      if (id == null) {
      throw new NullPointerException("id is marked non-null but is null");
      } else {
      this.id = id;
      return this;
      }
     }
    
     public UserLombok.UserLombokBuilder age(Integer age) {
      this.age = age;
      return this;
     }
    
     public UserLombok.UserLombokBuilder realName(String realName) {
      this.realName = realName;
      return this;
     }
    
     public UserLombok build() {
      return new UserLombok(this.id, this.age, this.realName);
     }
    
     public String toString() {
      return "UserLombok.UserLombokBuilder(id=" + this.id + ", age=" + this.age + ", realName=" + this.realName + ")";
     }
     }
    }
    종합 실례 2
    
    @Value
    public class UserLombok {
    
     @NonNull
     private Integer id;
    
     //     setter     ,    ,      
     @Setter(AccessLevel.PROTECTED)
     private Integer age;
    
     private String realName;
    
    }
    @ValueToString、EqualsAndHashCode、AllArgsConstructor、Getter 의 조합 주해 이다.
    생 성 된 코드
    
    import lombok.NonNull;
    
    public final class UserLombok {
     @NonNull
     private final Integer id;
     private final Integer age;
     private final String realName;
    
     public UserLombok(@NonNull Integer id, Integer age, String realName) {
     if (id == null) {
      throw new NullPointerException("id is marked non-null but is null");
     } else {
      this.id = id;
      this.age = age;
      this.realName = realName;
     }
     }
    
     @NonNull
     public Integer getId() {
     return this.id;
     }
    
     public Integer getAge() {
     return this.age;
     }
    
     public String getRealName() {
     return this.realName;
     }
    
     public boolean equals(Object o) {
     if (o == this) {
      return true;
     } else if (!(o instanceof UserLombok)) {
      return false;
     } else {
      UserLombok other;
      label44: {
      other = (UserLombok)o;
      Object this$id = this.getId();
      Object other$id = other.getId();
      if (this$id == null) {
       if (other$id == null) {
       break label44;
       }
      } else if (this$id.equals(other$id)) {
       break label44;
      }
    
      return false;
      }
    
      Object this$age = this.getAge();
      Object other$age = other.getAge();
      if (this$age == null) {
      if (other$age != null) {
       return false;
      }
      } else if (!this$age.equals(other$age)) {
      return false;
      }
    
      Object this$realName = this.getRealName();
      Object other$realName = other.getRealName();
      if (this$realName == null) {
      if (other$realName != null) {
       return false;
      }
      } else if (!this$realName.equals(other$realName)) {
      return false;
      }
    
      return true;
     }
     }
    
     public int hashCode() {
     int PRIME = true;
     int result = 1;
     Object $id = this.getId();
     int result = result * 59 + ($id == null ? 43 : $id.hashCode());
     Object $age = this.getAge();
     result = result * 59 + ($age == null ? 43 : $age.hashCode());
     Object $realName = this.getRealName();
     result = result * 59 + ($realName == null ? 43 : $realName.hashCode());
     return result;
     }
    
     public String toString() {
     return "UserLombok(id=" + this.getId() + ", age=" + this.getAge() + ", realName=" + this.getRealName() + ")";
     }
    }
    종합 실례 3
    로그 사용
    
    import lombok.extern.java.Log;
    
    @Log
    public class LogLombok {
    
     public void log() {
     log.info("    ");
     }
    }
    생 성 후 코드
    
    import java.util.logging.Logger;
    
    public class LogLombok {
     private static final Logger log = Logger.getLogger(LogLombok.class.getName());
    
     public LogLombok() {
     }
    
     public void log() {
     log.info("    ");
     }
    }
    위의 예 시 를 통 해 우 리 는 Lombok 이 우리 의 코드 를 크게 간소화 할 수 있다 는 것 을 알 수 있다.
    Lombok 의 장단 점.
  • 장점:
  • 개발 효율 을 높이 고 getter/setter,toString,builder 등 을 자동 으로 생 성 합 니 다.특히 클래스 가 계속 바 뀌 는 과정 에서 IDEA 가 자동 으로 생 성 하 는 코드 를 사용 하면 우 리 는 끊임없이 삭제 하고 다시 생 성 해 야 합 니 다.Lombok 을 사용 하면 자동 으로 완성 할 수 있 습 니 다.
    코드 를 간결 하 게 만 들 고 해당 하 는 템 플 릿 방법 에 지나치게 관심 을 가지 지 않 아 도 됩 니 다.그 중에서 getter/setter,toString,builder 는 모두 템 플 릿 코드 입 니 다.쓰기 힘 들 고 쓰 지 않 아 도 됩 니 다.또한 자바 14 에 서 는 record 를 지원 할 계획 이 었 고 원생 적 으로 이 템 플 릿 코드 를 해결 해 주 었 습 니 다.
    속성 을 수정 할 때 도 이러한 속성 으로 생 성 된 getter/setter 방법 등 을 간소화 합 니 다.
  • 단점:
  • 개발 자 마다 Lombok 프로젝트 를 동시에 개발 하고 Lombok 플러그 인 을 설치 해 야 합 니 다.
    속성 이름 을 재 구성 하 는 데 불리 합 니 다.대응 하 는 setter,getter,builder,IDEA 는 자동 재 구성 을 도 울 수 없습니다.
    소스 코드 의 가 독성 과 완전 성 을 낮 추고 소스 코드 를 읽 는 편안 도 를 낮 출 수 있 습 니 다.누가 템 플 릿 코드 를 읽 을 수 있 습 니까?
    컴 파일 시 오류 해결
    컴 파일 할 때 오류 가 발생 했 습 니 다.주해 처리 기 를 사용 하지 않 았 을 수도 있 습 니 다.Build, Execution, Deployment > Annotation Processors > Enable annotation processing。설정 이 완료 되면 프로그램 이 정상적으로 실 행 됩 니 다.
    피 갱 안내
  • 가능 한 한@Data 주 해 를 사용 하지 마 세 요.이 주 해 는 너무 완전 해서 유지 에 불리 합 니 다.당신 이 무엇 을 하고 있 는 지 알 지 않 는 한
  • 자바 기본 메커니즘 에 다른 구조 기 가 있 으 면 무 삼 구조 기 가 생 성 되 지 않 습 니 다.@AllArgsConstructor 주 해 를 사용 할 때@NoArgsConstructor
  • 를 추가 하 는 것 을 기억 하 십시오.
  • 클래스 정의 가 변화 단계 에 있다 면@AllArgsConstructor 주 해 를 사용 하 는 것 을 권장 하지 않 습 니 다
  • @Setter,@Getter주해 가 필요 하면 사용 범 위 를 좁 힐 수 있다
  • @ToString주 해 는 기본적으로 부모 클래스 의 정 보 를 생 성하 지 않 습 니 다.생 성 하려 면@ToString(callSuper=true)
  • @RequiredArgsConstructor@NoArgsConstructor 는 되도록 함께 사용 하지 마 십시오.무 참 구조 기 는 처리 할 수 없습니다@NonNull.그러나 직렬 화/반 직렬 화 된 것 은 무 참
  • 을 제공 해 야 합 니 다.
  • 팀 이 Lombok 을 사용 하지 않 기로 결 정 했 을 때 Lombok 플러그 인의 Delombok 원 키 로 제거 할 수 있 습 니 다.Refactor > Delombok에서
  • 다시 한 번 주의-@AllArgsConstructor 되도록 사용 하지 마 세 요.
    레 퍼 런 스
    https://projectlombok.org
    https://github.com/rzwitserloot/lombok
    Lombok 작업 원리
    작업 원 리 는 인터넷 자료 에서 나온다.
    Lombok 에서 사용 하 는 과정 에서 해당 주 해 를 추가 하기 만 하면 코드 를 더 이상 쓸 필요 가 없습니다.자동 으로 생 성 된 코드 는 도대체 어떻게 생 성 된 것 입 니까?
    핵심 은 주해 에 대한 해석 이다.JDK 5 는 주 해 를 도입 하면 서 두 가지 해석 방식 을 제공 했다.
  • 실행 시 분석
  • 실행 할 때 해석 할 수 있 는 주 해 는@Retention 을 RUNTIME 로 설정 해 야 합 니 다.반 사 를 통 해 이 주 해 를 받 을 수 있 습 니 다.java.lang.reflect 반사 패 키 지 는 인터페이스 AnnotatedElement 를 제공 합 니 다.이 인 터 페 이 스 는 주석 정 보 를 얻 는 몇 가지 방법 을 정의 합 니 다.Class,Constructor,Field,Method,Package 등 이 모두 이 인 터 페 이 스 를 실현 하여 반사 에 익숙 한 친구 들 에 게 이러한 해석 방식 을 잘 알 것 입 니 다.
  • 컴 파일 시 분석
  • 컴 파일 할 때 두 가지 메커니즘 이 있 는데 각각 간단하게 설명 합 니 다.
    1)Annotation Processing Tool
    apt 는 JDK 5 에서 생 성 되 었 습 니 다.JDK 7 은 만 료 로 표시 되 어 있 습 니 다.추천 하지 않 습 니 다.JDK 8 에서 완전히 삭 제 했 습 니 다.JDK 6 부터 Pluggable Annotation Processing API 를 사용 하여 교체 할 수 있 습 니 다.apt 가 교체 되 는 데 는 주로 두 가지 이유 가 있 습 니 다.
  • api 는 모두 com.sun.mirror 비표 준 패키지
  • javac 에 통합 되 지 않 았 습 니 다.추가 실행 이 필요 합 니 다
  • 2)Pluggable Annotation Processing API
    JSR 269 는 JDK 6 에서 가입 하여 apt 의 대체 방안 으로 apt 의 두 가지 문 제 를 해결 했다.자바 c 는 실행 할 때 이 API 를 실현 하 는 프로그램 을 호출 할 것 이다.그러면 우 리 는 컴 파일 러 를 강화 할 수 있다.자바 c 가 실행 하 는 과정 은 다음 과 같다.
    롬 복 은 본질 적 으로'JSR 269 API'를 구현 한 프로그램 이다.javac 를 사용 하 는 과정 에서 역할 을 하 는 구체 적 인 절 차 는 다음 과 같 습 니 다.
  • javac 는 소스 코드 를 분석 하여 추상 문법 트 리(AST)
  • 를 생 성 했다.
  • 실행 중'JSR 269 API'가 실 현 된 Lombok 프로그램 호출
  • 이때 Lombok 은 첫 번 째 단계 에서 얻 은 AST 를 처리 하고@Data 주석 이 있 는 클래스 에 대응 하 는 문법 트 리(AST)를 찾 은 다음 에 이 문법 트 리(AST)를 수정 하여 getter 와 setter 방법 이 정의 하 는 해당 트 리 노드
  • 를 추가 합 니 다.
  • javac 는 수 정 된 추상 문법 트 리(AST)를 사용 하여 바이트 파일 을 생 성 합 니 다.즉,class 에 새로운 노드(코드 블록)를 추가 합 니 다.
  • Lombok 소스 코드 를 읽 어 보 니 해당 주해 의 실현 은 모두 HandleXXX 에 있 습 니 다.예 를 들 어@Getter 주해 의 실현 은 HandleGetter.handle()에 있 습 니 다.Google Auto,Dagger 등 다른 라 이브 러 리 도 있 습 니 다.
    이상 은 자바 롬 복 의 소개,사용,작업 원리,장단 점 에 대한 상세 한 내용 입 니 다.자바 롬 복 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기