의존관계 주입은 크게 자동과 수동으로 나뉩니다.
수동 주입의 경우 @Configuration-@Bean를 사용하고 자동 주입은 @Component-@Autowired 를 사용합니다.
각각에 대해 살펴보도록 하겠습니다.
@Configuration-@Bean 의존관계 수동 주입
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new FixDiscountPolicy();
}
}
Inversion Of Control 를 위한 AppConfig 빈을 등록합니다. 이 Configuration 빈은 AppConfig@CGLIB 의 형태로 특수하게 등록되며 @Bean를 싱글톤으로 관리하도록 보장합니다. 싱글톤 컨테이너에 대해서는 이전에 글을 참고하도록 합니다.
2023.07.06 - [Spring☘️] - [Spring] 싱글톤 컨테이너
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
먼저 memberService() 가 빈으로 등록됩니다. 그 다음에 return new MemberServiceImpl(memberRepository()) 에서 의존 관계 주입을 시도합니다. memberRepository() 가 빈으로 등록되어 있지 않다면 등록을 하고 주입이 됩니다.
@Component-@Autowired 의존관계 자동 주입
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
@SpringBootApplication 를 항상 보셨을텐데 이 애노테이션이 실행되면 Component Scan 이 이루어집니다. @Component 를 찾아 모두 빈으로 등록을 한 후에 @Autowired 를 확인하여 의존 관계 주입이 됩니다.
이 때 생성자 주입, 수정자 주입, 필드 주입 등 여러가지가 있지만 생성자 주입이 권장되는 이유는 짧게 정리하면 다음과 같습니다.
- 의존관계 불변 보장 : 처음 생성자가 호출될 때 의존관계가 정해지고 이것에 대해 final 까지 선언을 하면 의존관계가 불변임이 보장된다.
- 프레임워크 의존 : 프레임워크에 의존하지 않고 순수 자바 코드로 테스팅을 하는 경우, 의존 관계 주입이 안 되었는데 코드 실행이 된다. 이때 컴파일 오류를 통해 사전에 오류를 잡을 수 있다면 좋았겠지만 그렇지 못하므로 테스트 용도로 좋지 못하다.
자동 주입 vs 수동 주입 뭐가 좋을까?
롬복의 지원까지 생각하면 자동이 훨씬 편리합니다. 그렇기 때문에 기본적으로 자동 주입을 써서 업무 로직이 명확하게 보이도록 하게 좋습니다. (@Controller, @Service, @Repository가 @Component 의 종류)
다만 기술적인 문제나 공통 관심사를 처리할 때는 수동빈으로 등록해서 설정 정보가 명확하게 드러나게 하는 경우가 좋습니다. 이 에시로는 SpringSecurityConfiguration, 서드파티 설정 등이 될거 같습니다.
또한 다형성을 이용하는 경우 수동으로 등록했을때 설정이 더 명확하게 드러나기 때문에 좋습니다.
'☘️Spring' 카테고리의 다른 글
[Spring] JPA N+1 문제 해결 (35) | 2023.10.30 |
---|---|
[Spring] MockMvcTest vs End-to-End Tests (1) | 2023.10.26 |
[Spring] web mvc 코드로 이해하기 (0) | 2023.09.02 |
[Spring] 싱글톤 컨테이너 (2) | 2023.07.06 |
[Spring] 스프링 컨테이너 개념 정리 (0) | 2023.07.04 |