본문 바로가기
공부/Spring

[Spring][스프링 핵심 원리] 의존 관계 주입 방법 및 옵션 처리

by 웅대 2023. 1. 19.
728x90
반응형

본 포스팅은 김영한 강사님의 인프런 강의 "스프링 핵심 원리 - 기본편"을 정리한 포스팅으로 강의 자료에서 사용한 자료를 사용했음을 밝힙니다.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8#

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

 

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을 사용하면 반드시 초기화를 해야하기 때문에 실수로 초기화를 안 하는 것을 방지할 수 있다.

728x90
반응형

댓글