[Spring Boot] @Autowired와 @Requiredargconstructor

의존성 주입

스프링에서의 의존성 주입 방법은 3가지가 있다.

Constructor

1
2
3
4
5
6
7
8
9
10
@Service
public class FooService {
private final BarService barService;

@Autowired
public FooService(BarService barService) {
this.barService = barService;
}
}

Setter

1
2
3
4
5
6
7
8
9
10
@Service
public class FooService {
private BarService barService;

@Autowired
public void setBarService(BarService barService) {
this.barService = barService;
}
}

Field

1
2
3
4
5
@Service
public class FooService {
@Autowired
private BarService barService;
}

Constructor Injection을 권장하는 이유

단일 책임의 원칙

생성자의 인자가 많아질수록 코드량이 많아지고 이는 의존관계가 커지게 된다. 따라서 단일 책임 원칙에 위배되게 된다. 그래서 Constructor Injection을 통해 의존 관계와 복잡성을 쉽게 알 수 있게 되어 리팩토링의 단초를 제공하게 된다.

테스트 용이성

DI 컨테이너에서 관리되는 클래스는 특정 DI 컨테이너에 의존하지 않고 POJO여야 한다. DI 컨테이너를 사용하지 않고도 인스턴스화 할 수 있고 단위 테스트도 가능해야 하며, 다른 프레임워크로의 전환도 쉬워야 한다.

불변성

Constructor Injection에서 필드는 final로 선언할 수 있다. 즉 불변 객체가 가능한데 비해 Field Injection에서는 final을 선언할 수 없기 때문에 객체가 변경 가능한 상태가 된다.

순환 의존성

Constructor Injection에서는 순환 의존성을 가질 경우 BeanCurrentlyInCreationException이 발생한다.

의존성 명시

의존 객체 중 필수는 Constructor Injection을, 옵션인 경우에는 Setter Injection을 사용할 수 있다.

Requiredargsconstructor을 사용한 의존성 주입

@Requiredargsconstructor 어노테이션은 @NonNull 어노테이션이 붙은 필드와 final로 선언된 필드들에 대해 생성자를 만들어 낸다. 이를 통해 Constructor Injection이 가능하게 된다.

1
2
3
4
5
6
@Service
@RequiredArgsConstructor
public class FooService {
private final BarService barService;
}

Author: Song Hayoung
Link: https://songhayoung.github.io/2021/02/22/Spring/autowiredVSrequiredargconstructor/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.