스프링 DI
스프링 컨테이너는 DI 컨테이너이다. 스프링은 DI를 적극적으로 활용해서 만들어져 있고 스프링을 이용해서 애플리케이션을 개발할 때 DI를 손쉽게 적용할 수 있도록 지원한다.

- 컨트롤러가 심플서비스에 의존함. 심플서비스가 변경되면 컨트롤러가 영향을 받음.


- 위의 문제를 해결하기 위해 헬로 서비스에 의존하게 함.
- 심플, 컴플렉스 둘 다 헬로 서비스를 구현함.
- 인터페이스를 구현한 클래스를 아무리 많이 만들어도 컨트롤러의 코드를 수정하지 않아도 됨.

- 실제 런타임이 되면 컨트롤러는 헬로서비스 인터페이스를 구현한 어떤 클래스의 오브젝트를 이용을 해야함.
- 어떤 오브젝트를 사용할 것인지 결정해야함.
- 심플서비스를 사용하기로 했을 때 컨트롤러는 인터페이스만 이용한다고 했으니 어느 클래스에서 만든 것을 사용하는 지 알 수 가 없음.
- 어떻게든 컨트롤러와 심플 서비스 사이의 연관관계를 만들어야함. -> 이 과정이 DI

- DI에는 제 3의 존재가 필요함. 이것을 Assembler라고 부름
- 컨트롤러가 헬로인터페이스를 구현한 어떤 클래스에 의존을 하지만 소스코드 레벨에서 수정하지 않고 런타임에서 심플이나 컴플렉스 서비스를 사용하기로 결정했다면 이것이 가능하게 해주는 것.
- 컨트롤러가 사용하는 오브젝트를 직접 new 키워드를 사용해서 만드는 대신 외부에서 오브젝트를 만들어서 컨트롤러에 주입을 해줌.
- 원래는 직접 의존관계가 없는 클래스들의 오브젝트를 가져다가 서로 관계를 연결하고 사용할 수 있게 함.

- Assembler == Spring Container
- 메타정보를 주면 클래스의 싱글톤 오브젝트를 만들고 이 오브젝트가 사용할 다른 의존 오브젝트가 있다면 그 오브젝트를 주입해주는 작업까지 수행.
- 주입 방법 : 컨트롤러를 만들 때 생성자 파라미터로 서비스 오브젝트를 넣어줌. factory method 같은 거로 빈을 만들어서 파라미터로 넘김. 컨트롤러 클래스에 property를 정의해서 setter method를 통해서 서비스 오브젝트 주입하는 방법 등.