DI 는 Dependency Injection의 약자로서, 우리 말로 하자면, '의존성 주입' 이라고 한다.
스프링은 기본적으로 DI를 기반으로 동작하기 때문에, 스프링을 잘 사용하려면 DI에 대한 이해가 필수적이다.
우리는 스프링을 사용하기 전, 이러한 방식을 통해 클래스 객체를 생성하고, 그 클래스 객체의 메서드를 사용했다.
스프링 프레임워크에서는 객체를 생성하고, 서로 관계를 설정하고, 이들의 생명 주기를 관리하는 컨테이너를 가지고 있다.
예를 들어, 'A' 클래스에서 'B' 객체가 필요하다면, 스프링 컨테이너에서 객체를 '주입(Injection)' 해주면 된다.
이러한 과정을 우리는 의존성 주입 즉, DI(Dependency Injection) 라고 한다.
✨이점으로는, 코드를 더욱 간결하게 만들어 주어, 가독성을 높여주고
의존성을 낮추어 구현이나, 테스트가 쉬워진다.
스프링에는 여러 컨테이너 구현체가 존재하며, 크게 두 가지로 분류 하자면, 아래와 같이 분류된다.
빈 팩토리(Bin Factory)
ApplicationContext
빈 팩토리는 단순히 객체를 생성하고 DI에 대한 기본적인 기능만을 제공해주기 때문에, 주로 빈 팩토리를 확장한 ApplicationContext 를 주로 사용하며, 여기서는 ApplicationContext 상위 계층에 Bin Factory가 위치한다는 것만 알고 넘어가자.
Bin Factory와 ApplicationContext는 인터페이스이기 때문에,
간단히 사용하기 위해서는 ApplicationContext 인터페이스를 구현한 클래스들을 사용한다.
자주 사용하는 ApplicationContext 구현 클래스로는,
WebApplicationContext 스프링 컨테이너는 MVC 패턴을 구현할 때 사용하게 될 것이다.
DI에서 의존 객체를 전달하는 방법으로는 크게 생성자 방식과, 프로퍼티 설정 방식으로 구분된다.
생성자 방식
생성자를 통해서 객체를 전달받는 방식
프로퍼티 방식
set()메서드를 이용해서 객체를 전달받는 방식
아래의 예제를 통해 자세히 알아보자.
public class Animal {
private Human human;
//생성자를 통해 컨테이너에서 의존 객체를 전달받음
public Animal(Human human) {
this.human = human;
}
public class Animal {
private Human human;
public void setHuman(Human human) {
this.human = human;
}
< bean>태그를 이용해서 스프링 컨테이너가 생성할 빈 객체에 대한 정보를 지정할때 사용한다. 주요 속성으로는 id, class가 있다.
id속성으로 지정한 빈의 이름은 다른 < bean>태그에서 참조할 때 사용된다.
class속성은 스프링 컨테이너가 생성할 객체의 클래스 이름을 값으로 갖는다.
다음은, < property> 태그나, < constructor-arg>태그를 이용해서 객체가 필요한 값을 설정한다.
기본 데이터 타입, wrapper 타입, String등의 값을 설정할 때에는, < value> 태그나 value 속성을 사용하고,
다른 bean 객체를 사용해야 할 때에는, value 태그나 value 속성을 대신, < ref>태그와 ref 속성을 사용한다.
< property>태그는, set프로퍼티이름() 형식의 메서드를 이용해서 값을 설정한다. < property> 태그의 name속성에 지정한 프로퍼티 이름과 일치하는 set()메서드를 사용해서 값을 설정한다.
< property name="name" value="kim"> = setName("kim")
< property name="human" ref="human"> = setHuman("human")
< value-ref>태그는 map객체의 값 설정을 빈으로 하고자 할 때 설정한다. 만약, id가 "human1"인 Human 객체를 Map 객체의 값으로 설정하고자 할때, < value-ref>human1로 설정한다.
나중에 빈 설정을 자동으로 한다고는 하지만, 이러한 list, map, set의 경우는 직접 값을 설정 해야 한다.
위에서 설명한, constructor 태그와 property 태그를 좀 더 간단하게 사용하고 싶다면, c 네임스페이스와 p 네임스페이스를 사용하면 된다.
c: 생성자 방식
p: 프로퍼티 방식
변수 이름을 넣지 않고도 c_인덱스, -ref 로 순서대로 넣어주면 프로퍼티에 값을 지정할 수 있다. 첫번째 인덱스는 0부터 시작한다.
(출처: 웹 개발자를 위한 Spring 4.0 프로그래밍, 저자 : 최범균)