의존성 주입 - @RequiredArgsConstructor

minjjai·2023년 1월 14일
0

Spring의 핵심 기술 중 하나는 DI(Dependency Injection), 의존성 주입이다.
이 글에서는 의존성 주입의 방법들과 @RequiredArgsConstructor 어노테이션을 이용한 생성자 주입에 대해서 더 자세히 다뤄보고자 한다.

주입 방식

생성자 주입

생성자 주입은 말 그대로 생성자를 통해서 의존 관계를 주입해주는 방법이다.
먼저 코드를 보자

@Controller
public class Controller {
	private Service service;
    
    @Autowired //Spring에서는 생성자가 한개일 경우 생략가능하도록 하고 있다.
    public Controller(Service service) {
    	this.service = service;
    }
}

생성자 주입은 생성자의 호출 시점에 1회만 호출되는 것이 보장된다.
주입받은 객체의 변경을 막거나 반드시 객체의 주입이 필요한 경우에 사용된다.
또한 Spring에서는 생성자 주입을 위한 여러 가지 방식들을 강하게 지원하고 있다.

Setter(수정자) 주입

수정자 주입은 필드 값을 변경하는 Setter를 통해서 의존 관계를 주입하는 방법이다.
Setter주입은 주입받는 객체가 변경될 가능성이 있는 경우에 사용되는데, 실제로 주입받는 객체의 변경이 필요한 경우는 극히 드물다.
때문에 Setter주입은 거의 사용되지 않는다.

@Controller
public class Controller {
	private Service service;
	private OtherService otherService;
    
    @Autowired
    public void setService(Service service) {
    	this.service = service;
    }
    @Autowired
    public void setOtherService(OtherService otherService) {
    	this.otherService = otherService;
    }
}

필드 주입(Field Injection)

세번째는 필드 주입이다. 필드 주입은 간결한 코드로 인해 과거에는 많이 사용되었으나, 외부에서 접근이 불가능하다는 단점이 있다. 과거보다 테스트 코드같은 것들의 중요성이 더해 가면서 객체에 접근이 불가능한 필드 주입은 사용되지 않게 되었다.

@Controller
public class Controller {
	@Autowired
    private Service service;
}

생성자 주입을 사용해야 하는 이유

1. 객체의 불변성 확보

개발시에는 의존 관계의 변경이 필요한 상황은 거의 없다.
setter주입 혹은 일반 메서드 주입은 불필요한 수정의 가능성을 열어두어 유지보수성을 떨어뜨린다.
생성자 주입은 수정/변경의 가능성을 배제하고 불변성을 보장하기 때문에 생성자 주입을 사용하는 것이 좋다.

2. 테스트 코드

테스트가 특정 프레임워크에 의존하는 것은 좋지 못하다고 한다.
그래서 테스트 시에는 순수 자바로 테스트를 작성하는 것이 좋다.
생성자 주입이 아닌 다른 방식으로 작성된 코드는 순수한 자바 코드로 단위 테스트를 작성하는 것이 어렵다.

만약 테스트 코드에서 @Autowired 어노테이션을 사용하기 위해 스프링을 사용하게 되면 단위 테스트 뿐 아니라 스프링이 빌드되는 시간들 때문에 테스트 시간/비용이 증가한다.

3. final & lombok

생성자 주입을 사용하면 final 을 사용할 수 있고 컴파일 시점에 의존성 누락을 확인할 수 있다.
추가로 lombok에는 @RequiredArgsConstructor라는 어노테이션이 있는데, 이 어노테이션은 final이 붙거나 null이면 안되는 객체들에 대한 생성자를 만들어 준다.
이런 lombok의 어노테이션들을 이용해 간결하고 깔끔한 코드를 작성할 수 있다.

4. 순환 참조 에러 방지

생성자 주입을 사용하면 애플리케이션의 구동 시점에 순환 참조 에러를 예방할 수 있다.
순환 참조란 A객체가 B객체를 의존하고, B객체도 A객체를 의존할 때 발생한다.
생성자 주입을 사용하면 이러한 에러를 사전에 잡을 수 있다.

추가로 '스프링에 비침투적인 코드 작성'등과 같은 장점이 있다.
참고 : 망나니개발자

profile
BackEnd Developer

0개의 댓글