오늘이라도
[Spring] @Autowired 대신 @RequiredArgsConstructor 본문
1. 개요
의존성 주입이란 것을 할 때 @Autowired 대신 생성자 주입을 활용하면 좋다고 합니다.
저도 공부 중이라 스프링 IoC, 빈, 의존성 같은 개념들은 잘 모르지만 일단 바로 적용할 수 있는 생성자 주입 방법을 간단하게 적어보겠습니다.
2. 의존성이 뭔데?
//HelloWorld.java
class HelloWorld {
private SayHello sayHello;
public HelloWorld() {
this.sayHello = new SayHello();
}
public startHelloWorld() {
this.sayHello.hello();
}
}
HelloWorld 클래스에서 hello함수가 호출되기 위해서는 SayHello 클래스가 필요합니다.
이 때 HelloWorld 클래스는 SayHello 클래스의 의존성을 가진다고 이야기합니다.
3. 왜 @Autowired를 지양해야 하는가?
@Controller
public class BoardController {
@Autowired private IBoardItemService boardItemService;
/* 이하 생략 */
}
@Autowired를 활용한 의존성 주입을 필드 주입이라고 합니다.
필드 주입은 사용법이 매우 간단해서 대부분 의존성 주입을 필드 주입으로 접하지만,
편리하단 것 말고는 장점이 없어서 스프링 4.3부터는 사용하지 않는 것을 권장한다고 합니다.
4. 그럼 @Autowired 대신 뭘 써야 할까?
Spring Team recommends: “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.
스프링팀에서는 항상 생성자 주입을 사용하는 것을 권장하고 있습니다.
생성자 주입을 사용할 경우 아래와 같은 장점이 있다고 합니다.
① 순환 참조 방지
② 테스트 코드 작성 용이
③ 코드 악취 제거
④ 객체 변이 방지 (final 가능)
위의 예제를 필드 주입에서 생성자 주입으로 바꿔보겠습니다.
@Controller
public class BoardController {
private final IBoardItemService boardItemService;
public BoardController(IBoardItemService boardItemService) {
this.boardItemService = boardItemService;
}
/* 이하 생략 */
}
5. 더 편하게 하려면?
생성자 주입으로 작성하게 되면 객체가 추가될 때마다 선언을 하고 생성자를 수정해줘야 하는데 여간 번거로운 게 아닙니다.
그럴 때는 lombok에서 제공하는 @RequiredArgsContructor 어노테이션을 활용하면 선언만으로도 생성자 주입이 가능하게 됩니다.
@Controller
@RequiredArgsConstructor
public class BoardController {
private final IBoardItemService boardItemService;
/* 이하 생략 */
}
- 참조
https://madplay.github.io/post/why-constructor-injection-is-better-than-field-injection
생성자 주입을 @Autowired를 사용하는 필드 주입보다 권장하는 하는 이유
https://ko.wikipedia.org/wiki/%EC%9D%98%EC%A1%B4%EC%84%B1_%EC%A3%BC%EC%9E%85
의존성 주입 - 위키백과