프로그래밍/JAVA Spring

[Spring 스프링] Spring Core - IoC(Inversion of Control), DI(Dependency Injection)

hectick 2023. 4. 24. 08:20

 

IoC(Inversion of Control, 제어의 역전)

 

IoC는 말그대로 제어가 역전되었다, 제어의 흐름을 바꾼다는 뜻이다. 

 

제어가 역전이 안된 상태부터 생각해보자. 처음 프로그래밍을 하던 시절을 생각해보면, 보통 프로그램은 main 메서드가 실행되고, 다음에 사용할 객체를 결정, 생성하고, 객체에 있는 메소드를 호출한다. 그리고 이 오브젝트 또한 자신이 사용할 객체를 스스로 생성하고 사용한다. 자신에 관련된 작업은 자신이 제어한다.

 

제어가 역전이 되었다는 것은 지금까지의 능동적인 과정이 수동적으로 바뀌는 것을 말한다. 객체가 자신이 사용할 오브젝트를 스스로 결정하지도 않고, 생성하지도 않는다. 다른 누군가가 외부에서 객체를 만들어서 자신에게 넘기면 그것을 사용한다. 

 

스프링에서는 애플리케이션 컨텍스트라는 것이 존재한다. 애플리케이션 컨텍스트는 IoC를 적용해서 관리할 모든 객체에 대한 생성 및 관계설정을 수행한다. 애플리케이션 컨텍스트는 객체에 대한 생성정보와 연관관계 정보를 별도의 설정 정보를 통해 얻는다.

 

 

IoC 컨테이너

IoC 방식으로 빈을 관리하는 컨테이너를 말한다. 스프링 컨테이너라고도 말한다.

 

스프링에서 애플리케이션의 뼈대를 이루며, 스프링이 직접 IoC 방식으로 관리하는 객체이다.

 

빈 팩토리

스프링의 IoC를 담당하는 핵심 컨테이너로, 빈을 등록, 생성, 조회, 반환 등 빈을 관리하는 기능이 있다. 보통은 빈 팩토리를 바로 사용하지 않고, 이를 확장한 애플리케이션 컨텍스트를 이용한다.

 

애플리케이션 컨텍스트

빈 팩토리를 확장한 IoC 컨테이너로, 기본적인 기능은 빈 팩토리와 동일하나, 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다.

 

 


 

DI(Dependency Injection, 의존관계 주입)

 

DI란 객체간의 의존관계를 외부에서 설정하고 주입하는 방식이다. 스프링이 제공하는 IoC 방식의 핵심이 DI 이다. 그래서 IoC 컨테이너가 DI 컨테이너라고도 불린다.

 

스프링 공식문서에는 두가지의 DI 방법을 소개하고 있다. 

 

생성자 주입(Constructor Injection)

생성자 주입의 경우, 생성자가 하나이면 @Autowired를 생략할 수 있다.

    @Component
    public class SimpleMovieLister {

        private final MovieFinder movieFinder;
		
        @Autowired
        public SimpleMovieLister(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
    }

 

수정자 주입(Setter Injection)

    @Component
    public class SimpleMovieLister {

        private MovieFinder movieFinder;

	@Autowired
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
    }

 

공식문서에서는 생성자 주입과 수정자 주입 중 생성자 주입을 권장하고 있다. 그 이유는 다음과 같다.

1. 불변 객체로 구현할 수 있음

2. 필수적인 의존관계가 null이 아님을 보장

3. 생성자 주입된 컴포넌트는 항상 완전히 초기화된 상태로 호출 코드에 반환됨

 

그리고 DI를 받으려는 객체는 자기 자신부터 컨테이너가 관리하는 빈이 되어야 한다고 한다~