본문 바로가기
Spring

[Spring] 스프링 IOC(Inversion of Control)와 DI(Dependency Injection)

by devjh 2021. 1. 14.
반응형

1. IOC컨테이너란?

 

스프링 IOC 컨테이너란 컴포넌트 스캐닝된 Bean 객체를 생성해주고, 관리해 주는 곳 입니다.

 

Bean과 컴포넌트 스캐닝이란?

frozenpond.tistory.com/71

 

[Spring] 스프링 빈(Bean)이란?

1. 스프링 빈(Bean)이란? 스프링의 진입점을 먼저 확인해보자. @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class,..

frozenpond.tistory.com

 

 

2. IOC란?

 

IOC란 Inversion of Control의 약자로 제어의 역전을 말합니다.

 

제어권을 개발자가 갖는게 아니라 외부가 갖고있다는 것을 의미하며

 

고수준의 모듈이 저수준의 모듈을 호출할때 인터페이스를 통해 호출하며

 

다형성을 안전하게 안전하게 제공함으로써 소프트웨어의 품질을 높이고 결합도를 낮추는 아키텍쳐이며

 

상속관계(의존성)가 제어의 흐름과 반대가 되는 현상을 말합니다.

 

@Controller
public class UserController {
    
    UserService userService;

    public UserController(UserService userService){
        this.userService = userService ;
    }
}

UserContrller의 UserService멤버는 해당 클래스가 생성될때 외부에서 넣어주게 되어있습니다.

 

@Controller는 컴포넌트 스캐닝을 통해 스프링 IOC 컨테이너안에서 생성되고 관리되는데

 

이걸 생성할때 누가 어떤 객체를 어떻게 알고 넣어준 건지가 궁금합니다.

 

이런 행위를 의미하는 용어가 DI입니다.

 

 

3. DI(Dependency Injection)

 

DI란 Dependency Injection의 약자로 의존성 주입이라고 한다.

 

필요한 의존성을 내부에서 new 키워드를 통해 생성하는것이 아니라 외부에서 주입을 해주는 방식을 뜻합니다.

 

UserService클래스는 이런식으로 @Service 어노테이션이 붙어있습니다.

@Service
public class UserService {

}

해당 클래스객체는 컴포넌트 스캐닝이 일어나서 스프링IOC 컨테이너에 들어가게되고

 

스프링 IOC 컨테이너는

 

스프링 빈으로 등록되는 객체들이 생성될때

 

생성자가 필요로 하는 객체를 알아서 찾아서 넣어줍니다

 

즉 Controller의 생성자에 Service객체를 필요로 하게 만들어놓으면 스프링 IOC에서 알아서 

 

싱글턴패턴으로 갖고있는 하나의 서비스객체를 넣어준 겁니다.

 

 

4. DI를 해주는 방법 3가지

 

위에서 사용한 방법을 생성자 주입이라고 합니다.

 

해당 생성자 위에 @Autowired를 붙여줘야 됐지만

 

스프링 버전 4.3이후로는 사용하지 붙여주지 않아도 정상적으로 DI가 됩니다 (lombok을 사용해서 주입하기도 한다)

public class UserController {
    
    UserService userService;

    @Autowired // 생략가능
    public UserController(UserService userService){
        this.userService = userService ;
    }
}

사실 생성자주입보다 빈번하게 사용되는 방법이

 

필드주입 방식입니다.

public class UserController {

    @Autowired
    UserService userService;
}

여러개의 Bean 객체를 주입받더라도 손쉽게 사용 가능하기에 많이 사용되지만

 

그만큼 결합도가 높아지게 되며

 

IOC가 아니라 내가 직접 객체를 만들면서 주입하려면 생성자주입보다 까다롭다는 단점이 있습니다.

(테스트 케이스 작성시 생성자주입을 하는것이 훨씬 간편하다)

 

마지막으로 Setter 주입 방법입니다.

public class UserController {
    
    UserService userService;

    @Autowired
    public void setUserService(UserService userService){
        this.userService = userService ;
    }
}

안씁니다.

 

생성자 주입을 하는 습관을 들이도록 합니다.

반응형

댓글