의존성 주입(Dependency Injection)
스프링의 핵심 프로그래밍 모델중 하나로 Ioc라고도 불리기도 한다 객체의 의존성을 객체 내부에서 정의해주는 대신에 외부에서 객체를 미리 정의하고 생성해서 넣어주는 개념을 말한다.
스프링 컨테이너
스프링은 스프링 컨테이너를 이용해서 내부의 Bean의 생명주기를 관리한다
- Bean의 생성, 관리. 제거 역활을 가지고 있다.
- 의존성을 주입하기 위해 스프링 컨테이너를 통해 객체를 생성하고 관리하고 있다.
- 컨테이너를 만들기 위해서는 XML 또는 애너테이션 기반의 자바 설정 클래스로 만들수가 있다.
왜 스프링 컨테이너를 사용했을까
일단 이유를 한마디로 표현하자면 객체간의 의존성을 낮추기 위해 만들어졌다고 볼 수 있다.
애플리케이션을 설계하고 개발하게 되면서 수많은 객체가 만들어지고 참조되가는 상황이 된다면 의존성이 높다고 볼수있는데 그렇게 된다면 핵심 요소인 객체지향프로그래밍의 조건을 맞출수가 없었다.
그래서 인터페이스를 통해 의존하도록해서 의존성을 낮추도록 했다.
현재의 스프링 컨테이너는 애너테이션 기반의 컨테이너 설정을 사용하고 있고 또한 공식적으로도 권장하고 있다.
기존에 사용하던 XML 방식이 존재하지만 애너테이션 기반의 컨테이너를 많이 사용한다는 점을 알아두자.
XML 기반 구성
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
컨테이너를 만들기 위한 방법은 ApplicationContext 인터페이스 구현체를 만드는 방법이다.
- 구성정보를 지정해서 컨테이너를 생성
- 애플리케이션 클래스는 구성 메타데이터와 결합해서 생성및 초기화를 거쳐서 실행가능한 애플리케이션을 갖추게 된다.
스프링에서 Bean의 조회는 상속관계가 있다면 그 부모타입일 경우 자식타입도 같이 불러온다
- 예시로 자바 객체의 최상위인 오브젝트를 조회하면 모든 스프링의 Bean이 조회된다.
스프링 컨테이너의 종류
넘겨받은 파라미터 값을 기준으로 정보를 참고해서 빈의 생성 또는 설정등을 총괄하는 컨테이너이다.
BeanFactory
- 최상위 인터페이스
- 컨테이너를 관리 제어
- getBean() 메서드를 통해 인스턴스화 할 수 있음
- @Bean 애너테이션을 통해서 등록을 할 수 있음
ApplicationContext
- BeanFactory의 기능을 상속받음
- 컨테이너의 부가 기능을 제공하고 있음
- MessageSource: 메세지 다국화를 위한 인터페이스
- EnvironmentCapable: 개발, 운영 등 환경변수 등으로 나눠 처리하고, 애플리케이션 구동 시 필요한 정보들을 관리하기 위한 인터페이스
- ApplicationEventPublisher: 이벤트 관련 기능을 제공하는 인터페이스
- ResourceLoader: 파일, 클래스 패스, 외부 등 리소스를 편리하게 조회
기존 자바 객체 생성과 스프링의 IoC 생성자 주입
// 기존 객체 생성
private final WorldRepo wordrepo = new WorldRepoImpl();
private final EarthIdle earthIdle = new EarthIdleInfo();
// IoC 또는 DI 생성자 주입
private final WorldRepo wordrepo
private final EarthIdle earthIdle
public Spaceservice(WorldRepo wordrepo, EarthIdle earthIdle){
this.wordrepo = wordrepo;
this.earthIdle = earthIdle;
}
- new를 사용해 만드는 객체는 강한 의존 관계다 생성자를 통해 객체를 생성하면 느슨한 의존 관계이다.
- 생성자 주입을 통해서 유연하게 구현 클래스를 변경할 수 있다.
- 객체의 주입은 설정에서 제어하게 된다.
빈(Bean)
빈은 스프링 컨테이너가 제어하는 재사용 소프트웨어 컴포넌트다. 즉 스프링에서 관리하는 자바 객체이다.
XML 또는 애너테이션을 통해 사용하고 있다.
BeanDefinition
빈을 실질적으로 BeanDefinition 추상화를 통해 사용할 수 있었다.
- 속성에 따라 컨테이너를 생성 관리할지 결정한다.
- 스프링은 메타정보를 BeanDefinition 인터페이스로 관리해서 실질적으로 설정을 XML이나 애너테이션으로 할 수 있는것이다.