ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 스프링 핵심 원리 - 의존관계 자동 주입
    Study/Spring 2025. 4. 16. 22:02

    다양한 의존관계 주입 방법

    • 의존관계 주입은 크게 4가지 방법 존재
      • 생성자
      • 수정자(setter)
      • 필드
      • 일반 메서드

     

    1) 생성자 주입

    • 특징
      • 생성자 호출 시점에 딱 1번만 호출되는 것이 보장
      • 불변, 필수 의존관계에 사용

     

    예시)

    @Component
    public class OrderServiceImpl implements OrderService {
    	
    	private final MemberRepository memberRepository;
    	private final DiscountPolicy discountPolicy;
    	
    	@Autowired // 생성자가 1개인 경우 생략 가능
    	public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    		this.memberRepository = memberRepository;
    		this.discountPolicy = discountPolicy;
    	}
    }
    

     

    2) 수정자 주입

    • setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해 의존관계를 주입하는 방법
    • 특징
      • 변경, 선택 가능성이 있는 의존관계에 사용
        • 외부에서 setter 메서드 호출할 경우 변경될 수 있음
        • 스프링 빈이 존재하지 않을 경우 의존관계가 맺어지지 않을 수 있음
      • 자바빈 프로퍼티 규약의 수정자 메서드(setXXX) 방식을 사용하는 방법임

     

    예시)

    @Component
    public class OrderServiceImpl implements OrderService {
    	
    	private MemberRepository memberRepository;
    	private DiscountPolicy discountPolicy;
    	
    	@Autowired
    	public void setMemberRepository(MemberRepository memberRepository) {
    		this.memberRepository = memberRepository;
    	}
    	
    	@Autowired
    	public void setDiscountPolicy(DiscountPolicy discountPolicy) {
    		this.discountPolicy = discountPolicy;
    	}
    }
    

     

    3) 필드 주입

    • 특징
      • DI 프레임워크가 없으면 아무것도 할 수 없음
        • 외부에서 변경이 불가능해서 테스트하기 힘듦 (외부에서 의존관계 주입하려면 결국 setter 메서드 제공해줘야 함)
      • 사용하지 말자!
        • 어플리케이션의 실제 코드와 관계 없는 테스트 코드에는 OK
          • @SpringBootTest를 사용해 스프링 컨테이너를 사용하는 경우에만 동작함

     

    예시)

    @Component
    public class OrderServiceImpl implements OrderService {
    	
    	@Autowired
    	private MemberRepository memberRepository;
    	
    	@Autowired
    	private DiscountPolicy discountPolicy;
    	
    }
    

     

    4) 일반 메서드 주입

    • 특징
      • 한 번에 여러 필드를 주입받을 수 있음
      • 일반적으로 잘 사용하지 않음
      • 수정자 주입과 동일한 문제점 갖음

     

    예시)

    @Component
    public class OrderServiceImpl implements OrderService {
    	
    	private MemberRepository memberRepository;
    	private DiscountPolicy discountPolicy;
    	
    	@Autowired
    	public void init(MemberRepository memberRepository) {
    		this.memberRepository = memberRepository;
    	}
    }
    

     

    생성자 주입을 선택해라!

    • 의존관계를 불변하게 만들 수 있음
      • 대부분의 의존관계 주입은 한 번 일어나면 어플리케이션의 종료 시점까지 변경할 일이 없음
      • 수정자 주입을 사용하면, setter 메서드를 public으로 열어두어야 하여 변경될 가능성 있음
      • 생성자 주입은 객체를 생성할 때 딱 1번만 호출되고 이후에 호출되는 일이 없음. 따라서 불변하게 설계할 수 있음
    • 의존관계 주입 누락 방지
      • DI 프레임워크 없이 순수한 자바 코드를 단위 테스트할 때 수정자 주입을 사용할 경우 의존관계 주입이 되지 않은 채 테스트가 수행되어 NPE 발생할 수 있음
    • final 키워드를 사용해 컴파일 시점에 의존관계 주입 오류 알 수 있음
      • 생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있음
      • 생성자에서 혹시라도 값이 설정되지 않은 오류를 컴파일 시점에 막아줌

     

    참고

    스프링 핵심 원리 - 기본편

    댓글

Designed by Tistory.