Spring에서는 Bean DI를 지원하는 어노테이션 @Autowired
와 @RequiredArgsConstructor
가 있다.
@Autowired
는 Bean 주입시마다 달아줘야하지만, @RequiredArgsConstructor
는 해당 클래스에 달고 private final로 Bean을 주입하면 되서 코드가 깔끔해지고 가독성이 높다고 느낀다.
이런 이유로 나는 @RequiredArgsConstructor
사용하고 있었는데 많은 글들이 @Autowired
대신 @RequiredArgsConstructor
를 사용하라고 한다.
왜일까? 이 두개는 무슨 차이가 있길래 그러는걸까?
@Service
public class AService {
@Autowired
private BService bService;
}
@Autowired
를 활용한 DI를 필드 주입이라고 한다.@Service
@RequiredArgsConstructor
public class AService {
private final BService bService;
}
@RequiredArgsConstructor
를 활용한 DI를 생성자 주입이라고 한다.Spring Team recommends: “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.
Spring 4.3부터는 @Autowired
사용을 지양하고 항상 생성자 주입을 사용하는 것을 권장한다.
아래와 같은경우 순환 참조 에러가 발생할 수 있다.
@Service
public class AService {
@Autowired
private BService bService;
}
@Service
public class BService {
@Autowired
private AService aService;
}
Spring Container의 도움 없이 테스트 코드를 편리하게 작성 할 수 있다.
단. @RequiredArgsConstructor
은 Spring Test쪽에서는 lombok 적용이 안되므로 사용할 수 없다.
final 선언이 가능하기 때문에 Runtime시 주입된 Bean 객체의 불변성을 보장한다.
여기서 말하는 생성자 주입하는 코드는 아래와 같다.
@Service
public class AService {
private final BService bService;
private final CService cService;
public AService(BService bService, CService cService)
{
this.bService = bService;
this.cService = cService;
}
}
위 처럼 생성자 주입으로 작성하게 되면 주입할 Bean이 많아지면 많아질 수록 정말 많이 번거롭다.
이런 번거로움을 해결해주고 코드를 줄여주며 생성자 주입 기능을 지원하는 Annotation이 @RequiredArgsConstructor
이다.