본문 바로가기
SW/개발

[Spring] 스프링 DI - 의존관계 주입

by PEKAH 2022. 4. 21.

스프링 백엔드 개발할 때마다 아무렇지 않게 @Autowired를 사용해 서비스 의존관계를 주입했었는데, 

 

어느 날 보니 IDE에서 경고메시지를 출력하고 있었다. 

 

Field injection is not recommended … Always use constructor based dependency injection in your beans

 

이게 먼가.. 하고 찾아봤더니, 스프링의 DI에는 Field Injection, Setter Injection, Constructor Injection 등의 의존성 주입이 있고, 그중 내가 사용한 Field Injection은 사용이 지양되는 방식인 것 같다.

 

하여 의존관계 주입에 대하여 살펴보았다.

 

Dependency Injection(의존관계 주입)

먼저 DI에 대해 알아보겠다.

 

강한 결합

객체 내부에서 다른 객체를 생성하는 것은 강한 결합도를 가지는 구조이다. A 클래스 내부에서 B 라는 객체를 직접 생성하고 있다면, B 객체를 C 객체로 바꾸고 싶은 경우에 A 클래스도 수정해야 하는 방식이기 때문에 강한 결합이다.

 

느슨한 결합

객체를 주입 받는다는 것은 외부에서 생성된 객체를 인터페이스를 통해서 넘겨받는 것이다. 이렇게 하면 결합도를 낮출 수 있고, 런타임 시에 의존관계가 결정되기 때문에 유연한 구조를 가진다.

 

SOLID 원칙에서 O에 해당하는 Open Closed Principle 을 지키기 위해서 디자인 패턴 중 전략 패턴을 사용하게 되는데, 생성자 주입을 사용하게 되면 전략 패턴을 사용하게 된다.

 

Field Injection(필드 주입)

필드 주입은 필드에 바로 의존 관계를 주입하는 방법이다.

변수 선언부에 @Autowired 어노테이션을 붙인다.

@Controller
public class TestController {
	
    @Autowired
    private TestService testService;
}

 

필드 주입을 이용하면 코드가 간결해지지만 외부에서 접근이 불가능하다는 점 때문에 사용을 지양해야 한다.

 

Setter Injection(수정자 주입)

수정자 주입은 필드 값을 변경하는 Setter를 통해서 의존관계를 주입하는 방법이다.

@Controller
public class TestController {
	
    private TestService testService;
    
    @Autowired
    public void setTestService(TestService testService) {
    	this.testService = testService;
    }
}

 

수정자 주입은 주입받는 객체가 변경될 가능성이 있는 경우에 사용한다.

 

Constructor Injection(생성자 주입)

생성자 주입은 생성자를 통해 의존 관계를 주입하는 방법이다.

@Controller
public class TestController {
	
    private TestService testService;
    
    @Autowired
    public TestController(TestService testService) {
    	this.testService = testService;
    }
}

 

생성자 주입은 생성자의 호출 시점에 1회 호출되는 것이 보장된다. 그렇게 때문에 주입받는 객체가 변하지 않거나, 반드시 객체의 주입이 필요한 경우에 강제하기 위해 사용할 수 있다. 

 

생성자 주입 방식을 사용하자!

생성자 주입방식은 아래와 같은 장점을 가진다.

  • 의존관계 설정이 되지 않으면 객체생성 불가 -> 컴파일 타임에 인지 가능, NPE 방지
  • 의존성 주입이 필요한 필드를 final로 선언 가능
  • 스프링에서 순환 참조 감지 가능 -> 순환 참조 시 앱 구동 실패
  • 테스트 코드 작성 용이

필드 주입방식은 아래와 같은 장점을 가진다.

  • 코드가 간결해진다.

 

확인하고 나니 생성자 주입방식을 이용하는 것이 좀 더 올바른 코드 작성 방법인 것 같다.!

댓글