728x90

 

 

의존관계 주입은 크게 4가지 방법이 있다.

  • 수정자 주입 (setter 주입)
  • 필드 주입
  • 일반 메서드 주입 
  • 생성자 주입 

 

👉수정자 주입(setter 주입)

  • setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법이다.
  • 선택,변경 가능성이 있는 의존관계에 사용한다.
  • 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Component
public class OrderServiceImpl implements OrderService{
 
    private MemberRepository memberRepository;
    private DisCountPolicy discountPolicy;
 
    @Autowired
    public void setMemberRepository(MemberRepository memberRepository){
        
        this.memberReposityory = memberRepository;
    
    }
 
    @Autowired
    public void setDiscountPolicy(DiscountPolicy discountPolicy){
        
        this.discountPolicy = discountPolicy;
        
    }
 
 
}
cs

 

👉필드 주입

  • 말 그대로 필드에 바로 주입하는 방법이다.
  • 코드가 간결해서 좋을거라고 생각할 수 있지만 외부에서 변경이 불가능 해서 테스트를 하기 힘들다는 치명적인 단점을 가지고 있다.
  • DI프레임워크가 없으면 아무것도 할 수 없다.
  • 필드 주입이 유용하게 쓰일수 있는 곳은 실제 코드와 관련이 없는 테스트 코드에서는 사용할 수 있다.
  • 스프링 설정을 목적으로 하는 @Configuration같은 곳에서만 특별한 용도로 사용된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
public class OrderServiceImpl implements OrderService{
 
    @Autowired
    private MemberRepository memberRepository;
 
    @Autowired
    private DisCountPolicy discountPolicy;
 
    
 
 
}
cs

 

 

👉일반 메서드 주입

  • 일반 메서드를 통해서 주입 받을 수 있다.
  • 한번에 여러 필드를 주입 받을 수 있지만 잘 사용하지는 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@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;         
 
}
cs

 

👉생성자 주입

  • 이름 그대로 생성자를 통해서 주입 받는 방법이다.
  • 생성자 호출 시점에 딱 한번만 호출되는 것이 보장된다.
  • 불변,필수 의존관계에 사용 
1
2
3
4
5
6
7
8
9
10
11
12
13
@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;         
 
}
cs

+@ 생성자가 하나만 있으면 @Autowired를 생략해고 자동 주입된다.

 

👉생성자 주입 권장

일단 대부분이 이 4가지 방법 중에 생성자 주입을 권장한다. 최근에는 스프링을 포함한 DI 프레임워크 대부분이 생성자 주입을 권장한다.

 

👉생성자 주입 권장하는 이유

불변

  • 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지의 의존관계를 변경할 일이 없다.
  • 그리고 대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안된다.
  • 수정자 주입을 사용하면, setXXX메서드를 public으로 열어 두어야 한다.혹여나 누가 변경할 수 도 있기때문에 좋은 설계는 아니다.
  • 생성자 주입은 객체를 생성할 때 딱 한번만 호출되서 이후에는 호출될 일이 없다.

또 다른 장점은 생성자 주입을 사용하면 주입데이터를 누락 했을 때 컴파일 오류가 발생한다.그래서 바로 알 수 있다는 장점이 있다.

생성자 주입시에 final키워드를 사용한다.생성자에 혹시라도 설정되지 않는 오류를 컴파일 시점에서 막아준다.

 

 

 

정리

  • 생성자 주입 방식은 프레임워크에 의존하지 않고, 순수한 자바 언어의 특징을 잘살리는 방법이기도 하다.
  • 기본적으로 생성자 주입을 사용하고, 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여하면 된다.
  • 생성자 주입과 수정자 주입을 동시에 사용할 수 있다.
  • 필드 주입은 되도록이면 사용하지 않는게 좋다.
728x90

'Dev > Spring' 카테고리의 다른 글

@RequestMapping에 대하여  (0) 2021.07.24
[Spring]@RestController 와 @Controller의 차이  (0) 2021.07.18
로깅(Logging)  (0) 2021.07.13
[Spring]의존성 주입(Dependency Injection)  (0) 2021.06.24
[Spring]@RequiredArgsConstructor  (0) 2021.06.23