본 포스팅은 김영한 강사님의 인프런 강의 "스프링 핵심 원리 - 기본편"을 정리한 포스팅으로 강의 자료에서 사용한 자료를 사용했음을 밝힙니다.
1. 생성자 주입
생성자를 통해서 의존 관계를 주입 받는다.
생성자 호출 시점에 딱 한 번만 호출되는 것이 보장된다.
불변, 필수 의존 관계에 사용
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
.
.
.
}
참고로 생성자가 하나만 있으면 굳이 @Autowired 어노테이션을 달지 않아도 된다.
스프링은 스프링 컨테이너에 스프링 빈을 등록한 다음에 의존 관계를 설정하는데 생성자 주입의 경우 스프링 빈으로 등록할 때 생성자가 호출되기 때문에 자동으로 의존 관계가 주입된다.
2. setter 주입
setter를 사용해서 의존 관계를 주입하는 방식이다.
@Component
public class MemberServiceImpl implements MemberService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
.
.
.
}
선택, 변경 가능성이 있는 의존 관계에 사용한다.
주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false)를 사용하면 된다.
3. 필드 주입
필드에 바로 주입하는 방식
@Component
public class MemberServiceImpl implements MemberService {
@Autowired private MemberRepository memberRepository;
@Autowired private DiscountPolicy discountPolicy;
.
.
.
}
외부에서 변경이 불가능하다.
DI 프레임워크가 없으면 아무것도 할 수 없다.
사용하지 않는 것이 좋다.
4. 일반 메소드 주입
일반 메소드를 통해서 주입 받는다.
@Component
public class MemberServiceImpl implements MemberService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository=memberRepository;
this.discountPolicy=discountPolicy;
}
.
.
.
}
동시에 여러 필드를 주입 받을 수 있다.
이렇게 의존 관계 주입 방식에 대해 알아보았다.
@Autowired 어노테이션을 사용해서 의존 관계를 주입할 때는 스프링 빈에 등록되어있어야 자동으로 의존 관계를 주입할 수 있다.
그런데 스프링 빈이 없어도 동작하게 만들 수도 있다.
1. required = false 사용
@Autowired(required = false)를 사용하면 의존 관계를 주입할 대상이 없으면 메소드가 호출되지 않는다.
2. @Nullable 어노테이션 사용
@Autowired
public void setNoBean2(@Nullable Member noBean2){
System.out.println("noBean2 = " + noBean2);
}
주입 대상이 없으면 null을 넣어준다.
3. Optional 사용
@Autowired
public void setNoBean3(Optional<Member> noBean3){
System.out.println("noBean3 = " + noBean3);
}
주입 대상이 없으면 Optional.empty를 넣어준다.
Optional과 @Nullable의 경 생성자 주입을 사용할 때 특정 필드는 주입 대상이 없어도 실행되게 끔 할 때 사용하기도 한다.
생성자 주입을 사용해야 하는 이유
1. 주입해야하는 의존 관계를 바로 확인할 수 있다.
@Component
public class MemberServiceImpl implements MemberService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository=memberRepository;
this.discountPolicy=discountPolicy;
}
.
.
.
}
위 멤버 서비스는 멤버 레포지토리를 주입해야한다.
만약 setter 주입같은 방식을 사용할 경우 memberService 객체를 새로 생성하고나서 어떠한 의존 관계를 주입해야하는지 확인 후 setter를 사용하여 의존 관계를 주입한다.
그러나 생성자 주입을 사용할 경우 반드시 memberService 객체를 생성할 때 의존 관계를 주입해야 하므로 개발자의 실수를 줄일 수 있다.
2. final 키워드를 사용할 수 있다.
final 키워드를 사용하면 딱 한 번 초기화를 보장하기 때문에 안정성이 높아진다.
그리고 final을 사용하면 반드시 초기화를 해야하기 때문에 실수로 초기화를 안 하는 것을 방지할 수 있다.
'공부 > Spring' 카테고리의 다른 글
[Spring][스프링 핵심 원리] 빈 생명주기 콜백 (0) | 2023.01.24 |
---|---|
[Spring][스프링 핵심 원리] 조회한 빈이 두 개 이상일 때 문제 해결 (0) | 2023.01.22 |
[Spring][스프링 핵심 원리] 스프링 컨테이너와 스프링 (0) | 2023.01.12 |
[InteliiJ] 인텔리제이 단축키 (0) | 2023.01.10 |
[Spring][인프런 스프링 입문] AOP가 필요한 상황 및 적용 (0) | 2023.01.06 |
댓글