막상 개발을 해보면, 대부분이 다 불변이고, 그래서 다음과 같이 생성자에 final 키워드를 사용하게 된다.
그런데 생성자도 만들어야 하고, 주입 받은 값을 대입하는 코드도 만들어야 하고
필드 주입처럼 좀 편리하게 사용하는 방법은 없을까?
다음 기본 코드를 최적화해보자.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
생성자가 딱 1개만 있으면 '@Autowired'를 생략할 수 있다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
lombok을 사용하기 위해서 몇가지 설정을 추가해줘야한다.
build.gradle
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
// lombok 설정 추가 시작
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
// lombok 설정 추가 끝
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.testng:testng:7.1.0'
// 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') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
build.gradle에 lombok 설정, 라이브러리 추가 시작, 끝 부분의 설정을 위의 코드처럼 추가해준다.
추가해주고 난 다음, 코끼리 모양 버튼을 눌러서 gradle reload 및 새로 추가한 설정들을 불러온다.
File > Settings > Plugins 에서 lombok을 검색하여 추가할 수도 있다.
롬복을 사용하기 위해서는 아래와 같이 설정을 추가해야한다.
File > Settings > Build, Execution, Deployment > Compiler > Annotation Processors에서
Enable anntation processing을 체크해줘야 롬복 사용이 가능하다
롬복을 테스트하기 위해서, 아래의 경로에 HelloLombok.java를 만든다.
HelloLombok.java
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.setName("asdfas");
String name = helloLombok.getName();
System.out.println("name = " + name);
}
}
출력하면 위와 같이 출력된 것을 볼 수 있다.
lombok은 getter와 setter를 자동으로 만들어준다.
OrderServiceImpl.java
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
- 롬복 라이브러리가 제공하는 @RequiredArgsConstructor 기능을 사용하면 final이 붙은 필드를 모아서 생성자를 자동으로 만들어준다.(위의 코드에는 보이지 않지만 실제 호출 가능하다.)
- @RequiredArgsConstructor를 붙여주면 필드마다 자동으로 의존관계를 주입해준다.
- 최종 결과는 다음과 같다
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
// final을 붙이면 생성자에서만 쓸 수 있는 것이 장점
// final이 붙으면 무조건 필수로 초기화 되어야하는 값이 된다.
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
}
이 최종 결과 코드와 이전의 코드는 완전히 동일하다. 롬복이 자바의 애노테이션 프로세서라는 기능을 이용해서 컴파일 시점에 생성자 코드를 자동으로 생성해준다. 실제 class를 열어보면 다음 코드가 추가되어 있는 것을 확인해볼 수 있다.
클래스 이름 위에 ctrl + F12를 눌러서
실제로 생성자가 들어 있음을 확인할 수 있다.
"정리"
최근에는 생성자를 딱 1개 두고, @Autowired 를 생략하는 방법을 주로 사용한다. 여기에 Lombok 라이브러리의 @RequiredArgsConstructor 를 함께 사용하면 기능은 다 제공하면서, 코드는 깔끔하게 사용할 수 있다.
'스프링 > 핵심 원리' 카테고리의 다른 글
[Spring] @Autowired 필드 명, @Qualifier, @Primary (0) | 2022.02.25 |
---|---|
[Spring] 조회 Bean이 2개 이상 발생하는 문제 (0) | 2022.02.22 |
[Spring] 생성자 주입을 선택하라! (0) | 2022.02.18 |
[Spring] 옵션 처리 (0) | 2022.02.18 |
[Spring] 다양한 의존관계 주입 방법 (0) | 2022.02.18 |
댓글