사용자가 매 번 객체를 생성하고, 관리할 때마다 객체 간의 결합성이 커진다. 그럴 때마다 코드의 복잡성은 커지며 사용자는 번거로움을 느낀다. 이것은 곧 요구사항 변경의 취약을 의미한다. 객체인스턴스의 생성, 소멸을 관리해주는 게 따로 있을 수 없을까?
컨테이너는 객체의 생성주기를 관리하고, 생성된 객체에게 추가적인 기능을 제공하는 것을 뜻한다.
스프링 프레임워크도 이러한 객체의 생성, 소멸, 의존성 등을 담당하는 컨테이너가 따로 있는 데 이것이 바로 IOC 컨테이너이다.
인스턴트의 생성부터 소멸까지 생명주기를 사용자가 아닌 컨테이너가 따로 관리해주어 사용자는 오로지 로직에만 집중하면 된다.

위 그림을 보자. 사용자는 Factory라는 클래스의 객체를 Container에 등록하고 싶다. 그러면 @Component나 @Bean을 통해 스프링 빈으로 등록하면 된다. 그러면 Factory 객체는 따로 사용자가 아닌 컨테이너가 따로 관리해준다. 사용자는 번거롭게 Factory객체를 생성을 하지않고 그저 @Autowired를 붙여 컨테이너에서 불러내주기(DI)만 하면 된다.
이렇게 사용자가 객체를 관리하는 것이 아닌 컨테이너가 따로 관리해 사용자가 로직에만 집중할 수 있게 하는 것은 제어의 역전 즉, IOC라고 한다.
사용자는 그저 객체를 생성하지 않고, @Autowired를 통해 객체를 삽입해 불러올 수 있는데, 이것을 의존성 주입 즉, DI라고 한다.