DI(의존성 주입)는 IoC라는 원칙을 구현하기 위해서 사용되는 방법 중 하나이다.
일반적으로는 생성자를 통한 의존관계 주입을 사용한다.
그러나 이런 방법을 사용하면 객체를 생성할 때마다 직접 주입할 객체를 작성해야하는 불편함이 생긴다.
이를 해결하기 위한 일차적인 방법으로 의존성 주입을 관리하는 설정 파일을 만들어서 관심사 분리를 통해 해결할 수 있다.
이는 프레임워크에서 사용하는 방식이 아닌, 단순 컨테이너를 활용해 객체의 의존관계를 주입하는 방식이다.
public class DependencyConfig {
public MemberService memberService() {
return new MemberService(memberRepository());
}
public MemberRepository memberRepository() {
return new MemberRepository();
}
public CoffeeService coffeeService() {
return new CoffeeService(coffeeRepository());
}
public CoffeeRepository coffeeRepository() {
return new CoffeeRepository();
}
}
스프링 컨테이너는 스프링 프레임워크의 핵심 컴포넌트이다.
스프링 컨테이너는 내부에 존재하는 애플리케이션 빈의 생명주기를 관리한다.
ApplicationContext를 스프링 컨테이너라 하고 인터페이스로 구현되어 있다.(다형성 적용)
객체를 사용하기 위해서 new 생성자를 사용해야 했으며, 애플리케이션에서 이런 객체가 무수히 많이 존재하고 서로 참조하게 되어 있었다.(서로 참조가 심할수록 의존성이 높다고 표현하며, 낮은 결합도와 높은 캡슐화가 객체지향 프로그래밍의 핵심 중 하나인데 높은 의존성은 이를 지키지 못하는 방법이 될 수 밖에 없다.)
여기서 객체 간의 의존성을 낮추기 위해 Spring 컨테이너가 사용된다.
스프링 컨테이너를 사용하면 구현 클래스에 있는 의존성을 제거하고 인터페이스에만 의존하도록 설계 가능하다.
new AnnotationConfigApplicationContext(구성정보.class)
스프링 컨테이너를 만드는 다양한 방법은 ApplicationContext 인터페이스의 구현체이다.
스프링 빈 조회에서 상속관계가 있을 시 부모타입으로 조회하면 자식 타입도 함께 조회한다.
파라미터로 넘어온 설정 클래스 정보를 참고해서 빈의 생성, 관계 설정 등의 제어작업을 총괄하는 컨테이너이다.
Application 생성자에 제공된 위치 경로 또는 경로는 컨테이너가 로컬 파일 시스템, Java CLASSPATH 등과 같은 다양한 외부 리소스로부터 구성 메타데이터를 로드할 수 있도록 하는 리소스 문자열이다.
// Annotation
ApplicationContext context = new AnnotationConfigApplicationContext(DependencyConfig.class);