본문 바로가기
[IT] Spring Boot (JAVA)

[Spring] 스프링 의존성 주입 (Dependency Injection) 개념 및 종류

by 오리엔탈킴 2022. 4. 22.

오늘은 Spring 프레임워크의 DI (의존성 주입, Dependency Injection)에 관해 공부를 하면서 정리를 해보도록 하겠습니다.

1. DI(의존성 주입)이란?

Spring Dependency Injection이란, 각 객체 간 의존관계를 스프링 컨테이너가 개발자가 정의한 Bean 등록 정보를 바탕으로 자동으로 주입해주는 기능입니다.

일반적인 다양한 기존 스프링 프로젝트를 보면, Controller에서 Service나 Repository 객체를 사용 시, new 키워드를 통해 컨트롤러에서 객체를 직접 생성하여 사용하지 않고 의존성 주입을 통해 스프링 컨테이너에 생성된 객체를 받아 사용하고 있는 것을 볼 수 있습니다. @Component, @Service, @Repository, @Controller 등의 어노테이션이 붙은 클래스들은 스프링 실행 시 스캔을 통해 개발자가 정의한 의존성 정보를 자동으로 bean 설정 정보에 등록을 하게 되어 의존성 주입이 동작하게 합니다.

이를 통해 객체간 결합도를 낮추고, 코드의 양을 줄여주고, 테스트를 용이하게 하여, 개발 및 유지보수를 더 쉽게 하게 하는 장점이 있습니다.

 

2. DI(의존성 주입) 종류

스프링에서 의존성을 주입하는 방법은 아래와 같이 3가지 방법이 있습니다.

  • 필드 주입 (Field Injection)

@Controller
public class TestController {

    @Autowired
    TestService testService;
    
}

가장 코드가 단순하고 저같은 경우 기존에 많이 봐왔고 자주 사용했던 방식인데요, 아래와 같은 단점이 있어 추천되지 않는 방식이라고 합니다.

  • 프레임워크 의존적 : 스프링 DI 컨테이너에서만 동작, 외부에서 수정 불가, 테스트의 어려움
  • final 선언 불가 : 객체 변경 가능 

 

  • 수정자 주입 (Setter Injection)
@Controller
public class TestController {

    private TestService testService;

    @Autowired
    public void setTestService(TestService testService) {
        this.testService = testService;
    }
    
}

수정자 주입 방식은 스프링 3.x대 버전에서 추천되었던 방식으로, 현재는 주입받는 객체가 변경될 가능성이 있을 경우에만 사용되는 방식이라고 합니다.

 

  • 생성자 주입 (Constructor Injection)
@Controller
public class TestController {

    private final TestService testService;

    @Autowired // 생성자가 1개만 있을 경우 생략 가능
    public TestController(TestService testService) {
        this.testService = testService;
    }
    
}

현재 스프링 프레임워크에서 가장 권장되는 방식입니다. 간략히 아래와 같은 장점이 있다고 합니다.

  • 테스트 용이 : 프로엠워크 의존적이지 않아 순수 자바 등 외부 테스트 코드 작성 가능
  • 객체 불변성 확보: final 선언 가능, 유지보수 용이성
  • 순환 참조 에러가 발생할 경우 컴파일 시 판단 가능

생성자 주입 방식도 Lombok의 @RequiredArgsConstructor를 이용하면 코드를 아래와 같이 간결하게 작성할 수 있습니다.

@Controller
@RequiredArgsConstructor
public class TestController {

    private final TestService testService;
    
}

 

반응형

댓글