의존관계 주입 방법 4가지
- 생성자 주입
- 수정자 주입 (setter 주입)
- 필드 주입
- 일반 메서드 주입
1. 생성자 주입
- 이름 그대로 생성자를 통해 의존관계를 주입 받는 방법
- 특징
- 생성자 호출시점에서 딱 한번만 호출되는 것을 보장한다.
- 장점
- 불변 : 두 번이상 호출이 안되기때문에 변하지 않음
- 필수 : 생성자를 통해 들어온 값이 무조건 있어야 함
- 생성자가 하나일때는 자동으로 @Autowired가 적용이 된다. (생략가능)
- 예시
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
//생성자 (생성자가 하나라서 @Autowired 생략가능)
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
컴포넌트 스캔할 때 OrderServiceImpl 를 스프링 빈으로 등록이 되면 @Autowired 어노테이션이 부여된 생성자가 있기 때문에 생성자를 호출을 하여 의존성 주입을 한다.
어떻게? 스프링 빈이 MemberRepository와 DiscountPolicy라는 타입의 빈(Bean)을 찾아서 인자로 받아들여 주입시키고 OrderServiceImpl 빈을 생성
즉 스프링은 OrderServiceImpl 빈을 생성할 때 MemberRepository와 DiscountPolicy의 구현체를 찾아와서 해당 인스턴스를 생성자를 통해 주입한다.
MemberRepository 구현체 [MemoryMemberRepository]
@Component
public class MemoryMemberRepository implements MemberRepository{ //MemberRepository의 구현체
private static Map<Long, Member> store = new HashMap<>();
@Override
public void save(Member member) {
store.put(member.getId(), member);
}
@Override
public Member findById(Long memberId) {
return store.get(memberId);
}
}
2. 수정자 주입 (setter 주입)
- memberRepository , discountPolicy 필드명에 set 붙이고 카멜표기법으로 필드값을 메서드로 통해 직접 수정하기
- setMemberRepository, setDiscountPolicy
@Component
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
//setter 의존관계 주입
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
System.out.println("memberRepository = " + memberRepository);
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
System.out.println("discountPolicy = " + discountPolicy);
this.discountPolicy = discountPolicy;
}
}
- * 생성자 필요 없음
[테스트 결과]
- 특징 (선택, 변경)
- 선택적으로 의존관계를 주입할 수 있다.
- @Autowired(required=false) : 원래는 @Autowired 의 기본동작은 주입할 대상이 없으면 오류가 발생하지만 주입할 대상 없이도 동작하게 된다.
@Autowired(required=false) //의존관계 안해도 됨.
public void setMemberRepository(MemberRepository memberRepository) { }
-
- 변경가능성 있는 의존관계
3. 필드 주입
- 이름 그대로 필드에 바로 주입하는 방법 (권장하지 않음)
- 특징
- 코드가 간결해서 외부에 변경이 불가능해 테스트하기가 어렵다.
- 실제코드와 관련없는 테스트 코드에 사용
- 예시
- memberRepository, discountPolicy 필드앞에 @Autowired 붙이기
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
4. 일반 메서드 주입
- 일반 메서드를 통해 주입 받을 수 있다.
- 특징
- 아무 메서드에 @Autowired 를 붙일 수 있다.
- 한번에 여러 필드를 주입 받을 수 있다.
- 그러나 생성자 주입이나 수정자 주입을 대부분 사용하기 때문에 일반 메서드 주입은 일반적으로 사용하지 않는다.
- 예시
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
//일반 메서드 주입
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
※ 참고
OrderServiceImpl 은 스프링 컨테이너가 관리하는 스프링 빈이라서 @Autowired 가 기능한다.
( OrderServiceImpl 는 @Component 을 붙였기 때문에 스프링 컨테이너에 의해 빈으로 관리하는 클래스다. )
일반 클래스는 @Autowired 를 적용해도 아무 동작을 하지 않는다.
반응형
LIST
'공부' 카테고리의 다른 글
Spring | 빈 생명주기 콜백이란?, 초기화 콜백과 소멸 전 콜백 (0) | 2023.12.02 |
---|---|
Spring | List, Map 으로 빈 모두 조회하기 (0) | 2023.12.01 |
Spring | @ComponentScan , @Autowired 의존관계 자동주입 (0) | 2023.11.29 |
Spring | BeanFactory , ApplicationContext , 스프링의 다양한 설정 형식 (자바코드, XML) (0) | 2023.11.28 |
Spring | 스프링 빈 조회 - 상속 관계 (1) | 2023.11.23 |