JPA를 공부하려고 자료를 찾다보니 @RequiredArgsConstructor 를 사용한 소스코드를 보게 되었다 무슨 코드인지 몰라 알아보니 final로 선언된 필드를 매개변수로 하는 생성를 자동으로 생성해준다고 했다.
엥 그러면 @Autowired 는? 이것도 자동으로 생성자를 생성해주는 걸로 알고있는데 라는 생각이 들어서 두 어노테이션을 공부하게 되었다. 찾아보니
Autowired는 필드 주입 방식의 의존성 관리 방법
- Field, Setter Method, Constructor(생성자)에 사용 가능하다.(@RequiredArgsConstructor와 다른점)
- 기본적으로 Type을 기준으로 의존성을 주입 (DI)동일한 Type의 빈(Bean)이 여러 개 존재할 경우 기본적으로 참조 변수의 - 이름과 동일한 Bean을 찾아서 의존성을 주입한다.(순환 참조가 일어날 수 있음)
- 이름을 기준으로 의존성 주입을 할 때 @Qualifier 어노테이션을 사용해서 DI 될 Bean을 지정
- 만약 동일한 Type의 Bean이 여러 개 존재할 경우에는 @Primary 어노테이션을 사용해서 의존성 주입이 될 Bean을 지정 가능하다.
@Autowired의 단점
(1) 단일 책임의 원칙 위반 가능성
(2) 코드 변이의 가능성
@RequiredArgsConstructor을 통한 생성자 주입 방식을 활용할 경우에는 final 옵션을 사용하기에 객체가 변질될 가능성이 배제된다.
But, @Autowired를 통한 필드 주입 방식은 final 옵션을 사용할 수 없기에 코드가 변질될 가능성이 존재한다.
이는 로직에 따라 큰 에러가 발생할 가능성이 있기 때문에 중요한 문제이다.
(3) 불확실한 참조
@Autowired는 DI가 타입(Type)이 같은 빈(Bean)이 발견되면 그냥 주입한다.
지금까지 의존성 주입이 간편했던 이유인데 이것이 문제가 되는 이유는 같은 Type의 다른 객체가 여러 개일 때 문제가 발생한다. DI가 Type만 보고 내려주기에 서로 다른 A타입의 객체가 2개 존재한다면 @Autowired는 Error를 띄울 수밖에 없다.
@RequiredArgsConstructor
- Lombok에서 지원하는 어노테이션
- final 키워드가 붙은 필드에 대해 생성자를 만든다.
- 얼핏 보기엔 필드 주입처럼 보이지만 생성자로 의존성 주입을 한다.
- 스프링 개발팀에서 생성자 주입을 사용할 것을 권장하는 이유는 한번 의존성 주입을 받은 객체는 프로그램이 끝날 때까지 변하지 않는 특징을 가지므로 불변성을 표시해주는 것이 좋기 때문이다. => 객체의 불변성(Immutability) 보장
@RequiredArgsConstructor 특징
(1) 코드 변이에 대한 안전성
@RequiredArgsConstructor는 생성자 중에서 final 키워드가 붙은 주입에만 생성자를 만들어준다.
final이 붙어있기 때문에 인스턴스가 생성될 때 1번만 참조되므로 코드 변이의 걱정은 사라진다.
(2) 순환 참조에 대한 안전성
생성자 어노테이션을 사용할 경우에 순환 참조가 일어날 시 Exception이 발생하여 컴파일 중에 에러가 발생한다.
이를 통해 Test 단계에서 순환 참조를 파악하여 수정할 수 있다
==> 하지만 @Autowired와는 달리 생성자만 가능하기 때문에 제한적이다, 그러므로 생성자 의존성 주입을 사용할 때는 Autowired 보단 RequiredArgsConstructor를 사용하는 것이 효율적일 것 같다!
여기서 순환 참조란?

클래스 A가 클래스 B를 참조하고
클래스 B가 클래스 C를 참조하고
클래스 C가 다시 클래스 A를 참조하는 경우를 말한다.
결론
순환참조가 발생하면, 객체 생성 시점에서 무한루프에 빠지게 되어
프로그램이 정상적으로 동작하지 않을 수 있다.
이러한 문제를 해결하려면 객체 간의 의존성 최소화가 필요하다
출처: https://ccomccomhan.tistory.com/143 [[꼼꼼한 개발자] 꼼코더:티스토리]
출처: https://backendcode.tistory.com/209 [무작정 개발:티스토리]
결론
결국엔 하나만 써야지 라는 생각은 버리는게 좋을 것 같다 각각 상황에 맞는 소스코드를 짜려고 생각하는 것이 제일 맞는 것 같다
'Back-End > Spring' 카테고리의 다른 글
[Spring security] 중복 로그인 방지 기능 만들다가 마주친 Maximum sessions of 1 for this principal exceeded 오류 + 리스너 개념 (0) | 2024.09.11 |
---|---|
[Spring] RestAPI와 @ResponseEntity (0) | 2024.09.10 |
[Spring Security] spring security 에서 CSRF 작동시키는 이유 (2) | 2024.09.09 |
[Spring] 의존성 주입이란? (1) | 2024.09.06 |