의존관계 주입 방법과 Lombok

이동건·2021년 4월 8일
0

Spring

목록 보기
4/5

다양한 의존관계 주입 방법

스프링은 빈을 쭉 등록한 다음 의존관계 주입을 쭉 진행한다.

이렇게 두 가지 라이프사이클로 진행된다.

스프링 빈을 생성하는 단계와 의존관계를 주입하는 단계.

생성자 주입만 빈을 등록하면서 의존관계 주입도 같이 일어난다.

다른 주입은 두번째 단계에서 의존관계 주입이 일어난다.

생성자 주입

  • 생성자 호출 시점에 딱 1번만 호출되는 것이 보장된다.
  • 불변, 필수 의존관계에 사용

Getter, setter가 필요 없다 —> 불변 의존관계
final이 붙으면 반드시 값이 존재해야한다. —> 필수 의존관계

생성자가 단 하나일 때는 @Autowired를 생략할 수 있다.

수정자 주입

  • 선택, 변경 가능성이 있는 의존관계에 사용

선택적으로 특정 값이 null이어도 가능하게한다 —> @Autowired(required = false)
특정 인스턴스를 바꾸고 싶다면 그냥 호출하면 되도록한다.
자바빈 프로퍼티 규약인 setter를 통한 주입이다.

필드 주입

  • 필드에 바로 주입하는 방법. private이어도 가능하다.
  • 하지만 외부에서 변경이 불가능한 단점이 있다. —> 테스트 힘들다

필드 인젝션은 안 쓰는게 좋다. DI 프레임워크가 없으면 아무것도 못한다.
테스트 코드에서나 쓰자.

일반 메서드 주입

  • 아무 메서드에 @Autowired 사용
  • 한 번에 여러 메서드를 사용할 수 있다.
  • 일반적으로 안 쓴다

쓰지 말자.
사실상 수정자 주입이랑 똑같긴 하다. 그래서 쓸 일이 더 없다.

의존관계 주입은 스프링 컨테이너가 관리하는 빈이어야 동작한다.

생성자 주입을 권장하는 이유

불변

대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안되기 때문이다.

생성자주입은 바뀌지 않는다.

수정자 주입은 set을 열어두어야 하기 때문에 실수로 바뀔 수 있다.

변경하면 안 되는 메서드 자체를 열어두는 게 좋은 설계가 아니다.

생성자는 딱 1번만 호출되므로 불변하게 설계할 수 있다.

누락

생성자 주입을 쓰면 final 키워드를 넣을 수 있다는 장점이 있다.

final을 하면 무조건 생성자을 통해 할당이 되어야 한다.

final을 쓰면 한번 생성 되면 안 바뀐다. 그리고 값이 무조건 필요하다. 실수로 누락하는 걸 방지해 준다. 생성자에서 값이 설정되지 않는 오류를 컴파일 시점에 막아준다.

수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되어서 final키워드를 사용할 수 없다. 생성자 주입만 final 키워드를 사용할 수 있다.

테스트

프레임워크 없이 순수한 자바 코드를 단위 테스트 하는 경우에 좋다.

수정자 의존관계를 쓰면 테스트 코드를 짤 때 값을 세팅을 해야함

크리에이트 오더만 테스트하고 싶어도 가짜를 만들어서 넣어주어야 한다.

누락이 되버리는 것이다.

수정자 메서드를 두면 의존관계가 뭐가 들어가는지 안 보인다.

생성자 주입을 쓰면 의존관계가 뭐가 들어가는지 볼 수 있고 내 맘대로 구현체를 집어 넣을 수 있다.

프레임워크에 의존하지 않고 순수한 자바 언어의 특징을 살리는 방법이다.

기본으로 생성자 주입을 쓰고 필수값이 아닌 경우 수정자 주입 방식을 옵션으로 부여하면 된다.

롬복(Lombok)과 생성자 주입의 시너지

개발 해 보면 대부분 불변성이 필요하다.

그래서 생성자에 final키워드를 사용하게 된다.

근데 생성자도 만들어야하고 주입받은 값을 대입하는 코드도 만들어야한다.

이걸 한 번에 해결해 주는 방법이 롬복이다.

롬복은 getter, setter, toString 등의 코드를 알아서 만들어 준다.

그 중에서도 스프링에서 많이 사용되는 것은 @RequiredArgsContructor이다.

@RequiredArgsContructor은 내 객체에 final이 붙은 변수를 파라미터로 받는 생성자를 만들어준다.

이는 대단한 기능이 된다.

왜냐.

최근에는 생성자를 딱 1개만 두고 @Autowired를 생략하는 방법을 주로 사용한다.

여기에 Lombok 라이브러리의 @RequiredArgsConstructor와 함께 사용하면 알아서 final이 붙은 변수를 파라미터로 받는 생성자를 만들어주기 때문에,

@Autowired가 생략된 생성자를 안보이게 만들어주는 것이 되므로,

기능은 다 제공되면서 코드는 깔끔한, 보이지 않는 생성자 주입을 사용할 수 있게 되는 것이다.

끝으로...

즉, 의존관계 주입과 Lombok은 엄청난 시너지가 나게 된다.

private final을 쓰니까 final을 사용하는 이점은 다 챙기면서 생성자 주입을 해 주기 때문에 생성자 주입으로 인한 이점을 다 챙기면서도 생성자가 하나만 있으면 @Autowired를 생략할 수 있다는 점을 이용해 Lombok을 써서 생성자까지 가려버려 모든 기능을 전부 다 제공하면서도 생성자는 가려버리는 깔끔한 코드가 완성되는 것이다.

profile
코드를 통한 세계의 창조

0개의 댓글