-
(스프링 기본) 18 - 다양한 의존관계 주입 방법 (생성자, 수정자, 필드, 일반 메서드)개발/Spring 2024. 10. 28. 09:33
■ 의존관계 주입 4가지
1. 생성자 주입
2. 수정자 주입(setter 주입)
3. 필드 주입
4. 일반 메서드 주입
■ 생성자 주입
- 생성자를 통해 의존 관계 주입하는 방법
- 생성자 호출 시점 딱 1번만 호출되는 것이 보장된다.
- 불변, 필수 의존관계에 사용
@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; }
생성자에 있는 값은 무조건 넣어주는 것이 관례이다.
따라서 final 로 처리하여 무조건 값을 넣도록 처리한다.
★ 생성자가 딱 1개만 있으면 @Autowired 를 생략해도 자동 주입된다. (스프링 빈에만 해당)
■ 수정자 주입(setter 주입)
@Component public class OrderServiceImpl implements OrderService { private MemberRepository memberRepository; private DiscountPolicy discountPolicy; @Autowired public void setDiscountPolicy(DiscountPolicy discountPolicy) { System.out.println("discountPolicy = " + discountPolicy); this.discountPolicy = discountPolicy; } @Autowired public void setMemberRepository(MemberRepository memberRepository) { System.out.println("memberRepository = " + memberRepository); this.memberRepository = memberRepository; }
다음과 같이 set 메서드를 통해서 해당 메서드에 @Autowired 를 붙여,
setter 생성자를 주입해도 동일한 값이 나온다.
생성자 주입의 경우, OrderServiceImpl 객체를 생성할 때 생성자를 불러야 함으로
빈을 등록함과 동시에 주입이 이루어진다.
setter 의 경우에는 빈을 등록하고 의존관계 주입 시 이루어진다.
* 수정자 주입 특징
- 선택, 변경 가능성이 있는 의존관계에서 사용
- 자바빈프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법
@Autowired(required = false) public void setDiscountPolicy(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; }
@Autowired 주입 대상이 없으면 오류가 발생한다.
따라서 주입할 대상이 없어도 동작하고자 한다면 required = false 처리하면 된다.
※ 자바빈 프러퍼티(=메서드로 접근하여 필드값 변경)
: 자바는 과거부터 필드 값을 직접 변경하지 않고 setXxx, getXxx 라는 메서드로 수정했는데
이를 자바빈 프로퍼티라고 부른다.
3. 필드 주입
@Autowired private MemberRepository memberRepository; @Autowired private DiscountPolicy discountPolicy;
의존관계를 바로 필드에 넣어주는 것이다.
- 외부에서 변경이 불가능해서 테스트 하기 힘든 치명적 단점이 있다.
- DI 프레임워크가 없으면 아무것도 할 수 없다.
- 만약 사용하려고 하면 그 값을 넣어주는 setter 를 또 넣어줘야 함으로 그럴바엔 setter 주입이 낫다.
@SpringBootTest class CoreApplicationTests { @Autowired OrderService orderService; @Test void contextLoads() { orderService.xxx } }
다음과 같이 애플리케이션 실제 코드와 관계 없는 스프링 테스트 코드를 진행할 때는 사용하기도 한다.
@Configuration @ComponentScan( excludeFilters= @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class) ) public class AutoAppConfig { @Autowired MemberRepository memberRepository; @Autowired DiscountPolicy discountPolicy; @Bean OrderService orderService() { return new OrderServiceImpl(memberRepository, discountPolicy); } @Bean(name = "memoryMemberRepository") public MemberRepository memberRepository() { return new MemoryMemberRepository(); } }
또는 스프링 설정 목적으로 하는 @Configuration 같은 곳에서는 특별한 용도로 사용한다.
왜냐하면 AutoAppConfig 는 스프링 코드에서만 사용할 것이기 때문이다.
4. 일반 메서드 주입
@Autowired public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
- 일반 메서드 통해서 주입 받을 수 있다.
- 한 번에 여러 필드 주입 받을 수 있다.
- 일반적으로 잘 사용하지 않는다.
※ 의존관계 자동 주입은 스프링 컨테이너가 관리하는 스프링 빈이어야 동작한다.
그렇지 않은 Member 같은 클래스에서 @Autowired 코드를 적용해도 아무 작동 안한다.
출처 : 김영한 스프링 핵심 원리 - 기본편
'개발 > Spring' 카테고리의 다른 글
(스프링 기본) 20 - 생성자 주입 선택해야 하는 이유 (1) 2024.10.28 (스프링 기본) 19 - 옵션 처리 (0) 2024.10.28 (스프링 기본) 17 - 컴포넌트 스캔 (0) 2024.10.24 (스프링 기본) 16 - @Configuration과 싱글톤 (바이트코드 조작) (0) 2024.10.24 (스프링 기본) 15 - 싱글톤 방식의 주의점 (공유필드) (0) 2024.10.24