회사 코드를 뜯어보는 중인데, 국비 때 배웠던 @Autowired와 다르게 사용되어있어서 어떤차이인지 검색해 보게되었다.
@Autowired 어노테이션은 세 가지 방법으로 나뉘어져있다
1. 필드주입 (국비 땐 필드주입만 써봤다)
@Service
public class OrderService {
@Autowired
private MenuRepository menurepository;
}
- 간단하다는 장점이 있지만 final을 사용할 수 없어서 외부에서 변경시킬 가능성이 있다
- 의존관계를 파악하기가 힘들다
- 순환참조 문제는 Spring boot 2.6패치 해결되어 메서드 호출시 cycle이 발생했다고 알려준다
2. 세터주입
@Service
public class OrderController{
private MenuService menuService;
//옵션을 추가해서 의존성주입시 빈이없는경우 뜨는에러를 미리방지
@Autowired(required = false)
public void setMenuService(MenuService menuService){
this.menuService = menuService;
}
}
- 세터도 간단하지만 역시나 외부에서 변경이 가능하다
- 객체 생성 후에도 언제든 의존성 주입이 가능하다, 다만 변경이 필요없도록 설계하는게 좋기때문에 생성자 주입을 권한다
3. 생성자주입
@Service
public class StoreServiceImpl implements StoreService{
private final MenuService menuService;
@Autowired //단일 생성자일 경우 어노테이션 생략가능
public StoreServiceImpl(MenuService menuService){
this.StoreService = StoreService;
}
}
- SRP(단일 책임의 원칙) 유지 : 생성자 주입 사용 시 해당 생성자 파라미터에 사용하고자 하는 필드를 모두 넣어주어야 하기 때문에 하나의 비즈니스 로직만 유지하려는 경각심을 가질 수 있다. (다만 롬복 사용 시에는 @RequiredArgsConstructor를 사용하면 되기때문에... Hmm...)
- 주입받을 필드를 final로 선언 가능(외부에서 해당 빈 변경 불가) : 인스턴스 생성 시 의존성 주입이 일어나고 final 필드가 초기화 된다
- 참조순환 방지(필드나, 세터주입은 객체 생성 시점에는 순환참조가 일어나는지 확인할 수 없다. 그러나 생성자 주입은 컨테이너가 빈을 생성하는 시점에서 객체생성에 사이클 관계가 생김)
- 단위테스트 작성 편리 : 필드주입 시엔 nullPoint에러가 발생하여 mokito등으로 해야지만 단위테스트가 가능하다. 생성자주입 시 결합도가 낮아 순수 자바코드로 테스트 가능(new를 통해 주입 될 객체를 생성할 수 있다)
'개발 > JAVA' 카테고리의 다른 글
[Spring] 스프링이란? 왜 레거시에서 spring boot를 쓰게된걸까? (2) | 2022.11.03 |
---|---|
[Java] 보조 스트림 (0) | 2022.08.20 |
[Java] 입출력 스트림 (0) | 2022.08.16 |
[Java] 컬렉션 프레임워크 - Map (0) | 2022.08.14 |
[Java] 컬렉션 프레임워크 - List, Set (0) | 2022.08.14 |