[spring] 의존관계주입의 종류와 옵션 (스프링 기본편 by 김영한)

su_y2on·2022년 1월 25일
0

Spring

목록 보기
21/30
post-thumbnail

의존관계주입의 종류

의존관계주입의 종류는 크게 4가지가 있습니다.


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

이때 생성자가 하나면 @Autowired생략가능합니다.



2. 수정자 주입(setter 주입)✨

수정자 주입은 setter를 통해서 의존관계를 주입하는 방법입니다. 선택과 변경의 가능성이 있는 의존관계에 사용하면 좋습니다. 이는 직접 필드의 값을 변경하지않고 get~, set~의 메서드를 이용하는 자바빈 프로퍼티의 규약을 따르는 방식입니다.

@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. 필드 주입🧨

필드주입은 필드(멤버변수)에 바로 의존성을 주입해주는 것입니다. 그래서 그냥 필드 옆이나 위에 @Autowired라고 붙여주면 됩니다. 정말 간단하지만 이 방법은 💣 치명적은 단점 💣 이 있습니다. 바로 외부에서 변경이 불가능합니다.

앞에 생성자나, 수정자 주입방법은 테스트 코드를 작성할 때 스프링을 돌리지 않고도 자바코드만으로 의존성을 주입해줄 수 있습니다. 하지만 필드주입은 스프링같이 DI프레임워크가 없으면 주입할 수 있는 방법이 없기 때문에 유연성이 떨어집니다. 그래서 테스트코드안에서 간단히 의존성 주입을 할 때 사용되며 실제 개발에는 권장되지 않습니다.

@Component
public class OrderServiceImpl implements OrderService {

        @Autowired
        private MemberRepository memberRepository;
        
        @Autowired
        private DiscountPolicy discountPolicy;
  }



4. 일반 메서드 주입

수정자 주입의 일반적인 케이스라고 생각하면 되는 방법입니다. 장점으로는 한번에 여러 필드에 의존성을 주입할 수 있다는 것이있습니다. 하지만 일반적으로 사용되는 방법은 아닙니다. 주로 1,2번안에서 끝내는게 좋습니다 :)

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






의존성 관계 주입의 옵션

주입할 스프링 빈이 없으면 일반적으로는 오류가 발생합니다. 이때 주입할 스프링 빈이 없어도 오류가 나지 않고 돌아가게 하는 방법은 3가지가 있습니다.


1. required = false

먼저 Autowired에 required값을 false로 만들어주는 것입니다. 지금의 예제에서는 Merber타입의 빈이 없다고 인식하고 false옵션을 보고 setNoBean1은 더이상 호출되지 않습니다. 따라서 출력문은 없습니다.

//호출 안됨
@Autowired(required = false)
public void setNoBean1(Member member) {
        System.out.println("setNoBean1 = " + member);
    }

2. @Nullable

두 번째 방법은 파라미터 앞에 @Nullable을 붙여주는 것입니다. 이렇게하면 null이 반환됩니다.

//null 호출
@Autowired
public void setNoBean2(@Nullable Member member) {
        System.out.println("setNoBean2 = " + member);
    }

3. Optional<>

마지막으로 Optional로 파라미터 타입을 묶어줍니다. 이렇게하면 Optional.empty가 출력됩니다.

@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
        System.out.println("setNoBean3 = " + member);
    }






결론은 생성자주입!

지금까지 여러가지 방법의 의존성 주입을 알아보았습니다. 대부분의 의존관계 주입은 한번 일어나면 애플리케이션이 종료할때까지 변경될일이 거의 없습니다. 따라서 수정자주입 같은 경우에는 set~메서드를 public으로 열어둬서 중간에 실수로 외부에서 바뀔 가능성이 있기 때문에 좋은 방법은 아닙니다. 이런면에서 생성자 주입이 좋습니다.

또한 생성자주입은 순수자바코드로 테스트를 작성할 때 누락된 파라미터가 있다면 컴파일에러가 납니다. 마지막으로 생성자주입을 하면 필드에 final 키워드를 붙일 수 있어서 생성자 주입이 일어나지 않으면 컴파일 에러를 내줘서 디버깅이 쉽습니다.

0개의 댓글