본문 바로가기

Spring

Spring - 의존성주입 방법의 비교(생성자 주입, Setter주입, field주입)

Spring의 DI를 할 수 있는 방법은 3가지 - 생성자 주입, Setter주입, Field주입.

 

 

생성자 주입

class Controller{
    
    private Service service;
    
    @Autowired
    public Controller(Service service) {
        this.service = service;
    }
    
    public void doServiceThing() {
        service.doSomething();
    }
}

장점

- 생성자 주입을 하면 일부러 Null을 넣지 않는 이상 주입되는 인스턴스(Service)가 항상 존재.

- 이 때문에 doServiceThing을 호출할 때, service가 null이어서 나타나는 NullPointerException이 일어나지 않음.

- 또한 의존관계를 주입하지 않으면 객체 생성이 불가능 -> 의존관계를 컴파일 타임에 알 수 있음.

단점

- 외부에서 다른 Service인터페이스를 구현한 다른 인스턴스로 변경 불가능 (부모 인스턴스를 다시 만들어야함.)

- 생성자 주입이 컴포넌트에 필요한 모든 의존성 제공을 보장하지만, 대부분의 컨테이너도 의존성 제공을 보장하는 메커니즘을 제공하며 이때는 사용자 코드를 프레임워크에 결합해야 하는 부담이 따를 수 있다는 점을 명심하기 바랍니다.(라고 하는데 이런 경우는 아직 모르겠음.)

(출처 : https://thebook.io/006987/ch03/02/06-04/)

 

 

 

Setter주입

class Controller{
    
    private Service service;
    
    @Autowired
    public void setService(Service service) {
        this.service = service;
    }
    
    public void doServiceThing() {
        service.doSomething();
    }
}

장점

- Setter를 통해 인스턴스 변경 가능

- 외부에서 주입 가능

- 명시적으로 객체를 주입하지 않더라도 적절한 기본값을 선택하게 할 수 있음(라고 하는데 이런 경우는 아직 모르겠음.)

(출처 : https://thebook.io/006987/ch03/02/06-04/)

단점

- Setter를 호출하기 전까지는 service인스턴스가 null일 수 있음. 이 상황에서 doServiceThing()을 호출하면 NullPointerException이 나올 수 있음.

 

 

 

Field주입

class Controller{
    
    @Autowired
    private Service service;
    
    public void doServiceThing() {
        service.doSomething();
    }
}

장점

- 간단

 

단점

- Setter주입의 단점과 생성자 주입의 단점을 모두 가지고 있음.

 

 

 

 

 

 

결국 :

Field주입은 추천되지 않는 방식. Field주입은 Setter주입이나 생성자 주입으로 바꾸자.

인스턴스를 변경해야하거나 외부에서 주입해야할 때는 Setter주입, 그 외에는 생성자 주입을 사용하자.