Dependency Injection

HwangJerry·2023년 5월 4일
0
post-custom-banner

의존성 주입

스프링의 큰 특징 중 하나는 제어의 역전(Inversion of Control, IoC)을 수행하는 스프링 컨테이너라는 점입니다. 스프링 컨테이너는 스프링 애플리케이션을 위해 의존성 주입(Dependency Injection) 작업을 수행합니다.

이는 스프링 컨테이너는 빈(Bean)이라는 단위로 객체를 관리하고, 개발자가 의존관계 주입 방식만 정해두면 개발자가 new 연산자를 활용하여 직접 호출하지 않고도 컨테이너가 객체를 주입해주는 것을 말합니다.

이를 통해 두 객체 간의 관계를 설정할 때 인터페이스를 사이에 두어 클래스 레벨에서 의존관계가 강하게 결속되는 것을 피하고, 런타임 시에 관계를 동적으로 주입하여 프로그램의 유연성을 향상시킵니다.

이는 스프링을 활용한 개발 기법 중 가장 중요한 포인트 중 하나인 느슨한 결합(Loosen Coupling)을 가능하게 하여 스프링 애플리케이션의 유지 보수성과 자유성을 보장하게 됩니다.

이를 구현하는 방법은 여러 가지가 있습니다.

생성자 주입

이 방식으로 사용하는 것을 적극 권장

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

의존관계 주입 방식을 지정하는 @Autowired 어노테이션을 생성자에 붙여두면 생성자를 통한 의존성 주입이 가능합니다. 대부분의 개발이 이 방식을 취하고 있으므로 Spring 4.3 이후부터는 클래스 내 생성자가 하나라면 @Autowired를 생략해도 빈으로 관리되는 객체를 주입받을 수 있습니다.

생성자 주입은 인스턴스를 생성시 무조건 호출되기 때문에, 객체의 불변성을 보장하고 객체 주입을 안정적으로 수행할 수 있습니다.

@RequiredArgsConstructor와 같이 사용하면 더욱 간단한 코드로 생성자 주입을 이뤄낼 수 있다. 하나의 생성자만 존재한다면 @Autowired를 생략해도 되므로, @RequiredArgsConstructor 어노테이션을 잘 활용하면 더욱 보기 좋고 간단한 코드를 작성할 수 있다.

물론, @RequiredArgsConstructor@NoArgsConstructor를 동시에 사용할 경우에는 생성자에 @Autowired를 명시적으로 사용해야 한다.

필드 주입

@Controller
public class Controller{
	@Autowired
    private Service service;
}

언뜻 보면 코드가 단순하여 편한 방법으로 인식될 수 있지만, 필드 주입을 선택하면 그 대상에 final을 선언할 수 없어 주입되는 객체의 불변성을 보장할 수 없고, 주입이 동시에 일어난다면 순환참조 이슈가 존재합니다.

Setter 주입

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

단순히 말하면 메서드를 통한 의존관계 주입을 선언하는 방식입니다. 이는 주입하는 객체를 변경해야 하는 경우에 선택할 수 있는 방식이긴 하지만, 이러한 경우는 매우매우매우매우매우 드무니 알고만 있으면 됩니다. 대부분의 경우 생성자 주입을 사용합니다.

profile
알고리즘 풀이 아카이브
post-custom-banner

0개의 댓글