스프링에서 의존성 주입 방법

June·2022년 5월 1일
0

우테코

목록 보기
36/84

학습 배경

스프링 프레임워크를 사용하며 의존 관계 주입 방법이 여러가지가 있는 것을 알았다. 왜 스프링은 이렇게 여러 가지 방법들을 만들어놨고, 각각 어떠한 차이가 있는지 궁금했다.

의존 관계 주입 방법

setter 주입

setter 수정자 메서드를 이용해서 의존관계를 주입 또는 변경하는 방법이다.

@Controller
public class MyController {
    private MyService service;
    
    ...
    
    public void setService(MyService service) {
        this.service = service;
    }
}

하지만 일반 자바 코드에서도 setter를 열어두게 되면 변경이 어디서 일어나는지 관리가 안되는 단점이 있듯이 마찬가지 단점이 적용된다. 불필요하게 수정의 가능성을 열어두게 된다.

또한 처음 객체를 생성했을 때 필요한 의존 관계가 완전히 주입되지 않을 수 있어 NullPointerException 같은 예외로부터 안전하지 못하다.

공식문서에 따르면 기본적으로 setter를 통한 의존성 주입을 지양해야 하지만, 상호 참조 같은 문제가 있을 때는 setter를 통해서 해결할 수 있다.

하지만 애초에 생성자 방식을 사용할 때 순환참조가 발생하면 애플리케이션 구동 시점에 에러가 발생해서 예방 가능하다.

필드 주입

이름 그대로 필드에 바로 주입하는 방법이다.

@Controller
public class MyController {
    @Autowired
    private MyService myService;
    ...
}

코드가 간결하다는 장점이 있지만 외부에서 변경이 불가능해서 테스트 하기 힘들다. 또한 DI 프레임워크에 굉장히 의존적이다.

생성자 주입

빈 객체를 생성하는 시점에 모든 의존 관계를 주입하는 것이다.

@Controller
public class MyController {
    private final MyService myService;
    
    public MyController(MyService myService) {
        this.myService = myService;
    }
}

생성자 호출 시점에 한번만 호출된다. 스프링 4.3 부터는 생성자가 하나이면 @Autowired 애노테이션을 붙이지 않아도 된다. setter를 사용하지 않으므로 불변성을 보장해주는 효과가 있다.

결론

세 종류의 의존성 주입 설정 방법이 있지만, 생성자를 통한 방식이 다른 방식들 보다 낫다.

0개의 댓글