Spring/김영한 스프링 핵심원리 - 기본편

[섹션 7-4] 롬복과 최신 트렌드

보름달빵 2024. 2. 28. 23:03

 

 

의존 관계 주입을 자동으로 해줄 때 생성자 주입이 좋긴 하지만 코드가 많다...

생성자의 값을 설정해주는 코드를 넣어줘야하므로!

 

필드 주입의 경우 필드에 어노테이션 하나만 붙이면 끝인데.... 

 

 

생성자 주입을 필드 주입처럼 편리하게 사용하는 방법이 없을까?

 

롬복을 이용하자 

 

 

 

 


 

롬복 라이브러리 적용 방법 

 

build.gradle에 코드 추가하기 

//lombok 설정 추가 시작
configurations {
    compileOnly {
       extendsFrom annotationProcessor
    }
}
//lombok 설정 추가 끝

 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    //lombok 라이브러리 추가 시작
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    //lombok 라이브러리 추가 끝
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

 

build.gradle 전체 코드

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.2'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'
java {
    sourceCompatibility = '17'
}

//lombok 설정 추가 시작
configurations {
    compileOnly {
       extendsFrom annotationProcessor
    }
}
//lombok 설정 추가 끝




repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    //lombok 라이브러리 추가 시작
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    //lombok 라이브러리 추가 끝
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

/*
tasks.named('test') {
    useJUnitPlatform()
}
*/

 

 

 

  1. External Libraries 에서 lombok 있는지 확인 

 

 

 

 

2. Preferences(윈도우 File Settings)>  plugin > lombok 검색 설치 실행 (재시작)

 

 

 

3. Preferences >  Annotation Processors 검색 Enable annotation processing 체크 (재시작)

 

 

4. 임의의 테스트 클래스를 만들고 @Getter, @Setter 확인

 

package hello.core;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class HelloLombok {

    private String name;
    private int age;

    public static void main(String[] args) {
        
        HelloLombok helloLombok = new HelloLombok();
        helloLombok.setAge(10);
        int age1 = helloLombok.getAge();
        System.out.println("age1 = " + age1);

    }
}

 

 

원래 자바는 우리가 직접 getter와 setter메서드를 만들어줘야했다.

하지만 롬복의 @Getter, @Setter 를 이용한다면 메서드 없어도 알아서 만들어주므로 

코드가 깔끔해진다. 

 

이것들 이외에도 생성자와 관련한 것들도 있고 종류가 굉장히 많다! 

 

앞으로는 롬복을 사용해서 코드를 좀 더 간결하게 작성해보자


 

 

 

OrderServiceImpl 기존 코드

@Component
public class OrderServiceImpl implements OrderService{

      private  final MemberRepository memberRepository;
      private  final DiscountPolicy   discountPolicy;
      
     // @Autowired 
      public OrderServiceImpl(MemberRepository memberRepository,@Qualifier("rateDiscountPolicy") DiscountPolicy discountPolicy) {

        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

 

  • 생성자가 하나면 @Autowired를 생략해도 된다. 
  • 이제 여기에 롬복을 적용시켜보자 

 

@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{

      private  final MemberRepository memberRepository;
      private  final DiscountPolicy   discountPolicy;

   }

 

  • @RequiredArgsConstructor : 필수로 값을 넣어줘야하는 객체(final로 설정된 필드)를 모아 생성자를 만들어준다.
  • OrderServiceImpl에서 final로 설정된 것은 memberRepository, discountPolicy
  • 따라서 이 두 값을 매개변수로 하는 생성자를 알아서 만들어준다
  • 즉, @Autowired로 필드에 직접 주입을 받는 것과 같은 것이다 ( 물론 생성자를 이용해서!! ) 

 

결국 ,  저렇게 긴 코드가 어노테이션 하나와 같은 것이다. 

 

@RequiredArgsConstructor
public OrderServiceImpl(MemberRepository memberRepository,@Qualifier("rateDiscountPolicy") DiscountPolicy discountPolicy) {

        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

 

 

이 최종결과 코드와 이전의 코드는 완전히 동일하다. 롬복이 자바의 애노테이션 프로세서라는 기능을 이용해서 컴파일 시점에 생성자 코드를 자동으로 생성해준다. 실제 java class를 열어보면 다음 코드가 추가되어 있는 것을 확인할 수 있다.

 

 public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
 
     this.memberRepository = memberRepository;
     this.discountPolicy = discountPolicy;
 }