의존관계 자동주입

NNIIE·2022년 4월 22일
0

spring

목록 보기
9/12

의존관계 주입방법

생성자 주입

  • 생성자를 통해 의존관계를 주입하는 방법

    • 생성자 호출시점에 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;
      	}
      }

수정자 주입 (setter 주입)

  • setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해 의존관계를 주입하는 방법

    • 선택, 변경 가능성이 있는 의존관계에 사용

    • 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법

      @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;
      	}
      }

프로퍼티 규약 : 자바빈 프로퍼티, 자바에서는 과거부터 필드의 값을 직접 변경하지 않고, setXxx, getXxx 라는 메서드를 통해서 값을 읽거나 수정하는 규칙


필드주입

  • 필드에 바로 주입하는 방법.
    • 코드가 간결해지지만 외부에서 변경이 불가능해서 테스트 하기 힘들다는 치명적인 단점이 있다.
    • DI 프레임워크가 없으면 아무것도 할 수 없다.
    • 권장하지 않는다
      애플리케이션의 실제 코드와 관계 없는 테스트 코드
      스프링 설정을 목적으로 하는 @Configuration 같은 곳에서만 특별한 용도로 사용
      @Bean
      OrderService orderService(MemberRepository memberRepoisitory, DiscountPolicy
      						discountPolicy) {
      	new OrderServiceImpl(memberRepository, discountPolicy)
      } 

일반 메서드 주입

  • 일반 메서드를 통해서 주입 받을 수 있다
  • 한번에 여러필드를 주입받을 수 있다
  • 일반적으론 잘 사용 X
@Component
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;
   }
}

생성자 주입을 선택하자!

과거에는 필드 주입을 많이 사용했지만, 요즘은 스프링을 포함한 DI프레임워크 대부분이 생성자 주입을 권장한다.

  • 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없다. 오히려
    대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안된다.(불변해야 한다.)
  • 수정자 주입을 사용하면, setXxx 메서드를 public으로 열어두어야 한다.
  • 누군가 실수로 변경할 수 도 있고, 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아니다.
  • 생성자 주입은 객체를 생성할 때 딱 1번만 호출되므로 이후에 호출되는 일이 없다. 따라서 불변하게 설계할
    수 있다.
  • 순수한 자바 코드 단위 테스트를 할 수 있다.

final

  • 수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되므로, 필드에 final 키워드를
    사용할 수 없다. 생성자 주입 방식만 final 키워드를 사용할 수 있다.
  • 생성자 주입을 사용할 경우 필드에 final 키워드를 사용할 수 있기 때문에 컴파일 단계에서 오류를 발견하기 쉬워진다

lombok

  • lombok 적용시 lombok 라이브러리가 제공하는 @RequiredArgsConstructor 기능을 사용해 final이 붙은 필드를 모아서 생성자를 자동으로 만들어준다.
    @Component
    @RequiredArgsConstructor
    public class OrderServiceImpl implements OrderService {
    	private final MemberRepository memberRepository;
       private final DiscountPolicy discountPolicy;
    }
  • 최근에는 생성자를 딱 1개 두고, @Autowired 를 생략하는 방법을 주로 사용한다. 여기에 Lombok
    라이브러리의 @RequiredArgsConstructor 함께 사용하면 기능은 다 제공하면서, 코드는 깔끔하게
    사용할 수 있다.

0개의 댓글