아래와 같은 클래스가 있다.
public Class A{ private B b; public A(){ b = new BB(); } }
A 클래스는 B 클래스에 의존적이다.
만약 B를 구현하는 성능이 휠씬 좋은 BBB클래스를 사용해야 할 경우,
모든 b = new BB(); => b = new BBB()로 고쳐야 한다.
배포할때 소스파일이 아니라 컴파일된 클래스 파일만 배포한다.
필요한 코드를 수정하는것보다 텍스트로 된 xml에 변화될수 있는 정보들을 저장하는것이 낫다.
방법1: Inversion of Control (IoC)기능을 이용
A->B 의존성을 가질때 B의 변화가 있어도 A의 코드에 영향이 없도록 하기 위해서 B의 생성을 컨테이너에게 넘겨야 한다.
public A(){ b = new BB(); }
을 아래와 같이 바꾼다.
public A(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml"); b = (B) ctx.getBean("b"); //Dependency Lookup }
컨테이너에게 어떻게 B(의존객체)를 만들 것인가를 알려주기 위해서 xml을 만들고 xml을 참조해서 ApplicationContext를 만들면 그때부터 B의 생성에 관한 부분은 xml로 제어가 가능해진다.
context.xml을 참조해서 컨테이너를 시작하라는 뜻.
ApplicationContext ctx = new ClasspathXmlApplicationContext("context.xml");
context.xml 추가
<bean id="b" class="study.spring.BB" />
A가 컨테이너를 이용해서 B가 만든 오브젝트를 사용해야 하는데
Dependency Lookup 컨테이너에게 내가 필요한 객체를 달라고 요청하는 것.
ctx.getBean("id") 이렇게 id를 통해서 요청하면 되고,
그것을 객체가 구현한 인터페이스로 casting해서 그때부터 사용 되는 것.
A->B구조에서 B가 변해도 A의 코드에 영향을 주지 않도록 A에서 B를 직접 lookup하도록 코드를 넣었다. 이 부분이 코드가 일일히 들어가는데, A에서 그 lookup 코드를 없이 하도록 만들어본다.
Dependency Injection(DI)
방법2:Dependency Injection을 이용(injection은 뭔가를 삽입, 주입한다는 뜻).
기존에는 A가 B를 가져오는 방식(lookup)이고 이제는 A에 B를 집어넣는 방법(injection)을 쓴다.
두 가지가 필요한데
1. A에 B를 넣을 수 있는 방법이 있어야 하고,
2. 그걸 넣어주는 누군가 있어야 한다
1. A에 B를 넣는 방법 중 제일 간단한 것은 setter를 만든다. 외부에서 값을 집어 넣을 수 있다.
예제코드 (A --> B)
public A(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml"); b = (B) ctx.getBean("b"); //Dependency Lookup }
아래와 같이 바꾼다.
public void setB(B b) { this.b = b;}
전에 것이랑 비교하면 생성자에서 lookup코드가 없어지고 setter 메서드를 추가
2. A를 컨테이너가 관리하는 빈으로 만드는 거다.
다음에 A에다가 B를 집어넣어 줘야 하는데 그걸 누가 넣어줘야 하는데 그 말은 A에다가 누군가 외부에서 관리가 필요하다는 말이다. 즉 A도 컨테이너가 관리하는 객체 즉 bean이어야 한다는 것이다. 결국 A, B 두개 다 컨테이너가 관리하는 대상이 된다.
A의 생성이나 setter를 이용한 B의 삽입 등을 다른 놈한테 맡겨야 하는데 그렇게 오브젝트를 관리해주는 것을 container라고 한다. 따라서 A도 컨테이너가 관리하는 대상이 되여야 하는데 container managed object(bean-container가 관리해주는 오브젝트)가 되어야 한다.
context.xml 추가
<bean id="A" class="study.spring.A"> <property name="b" ref="b"/> </bean> <bean id="b" class="study.spring.BB" />
이렇게 A->B 구조에서 A도 완전히 관리대상으로 하면 xml에 A->B를 정의해주기만 하면 A를 가져올때 B도 만들고 자동으로 의존성도 삽입해주는 것을 Dependency Injection이라고 한다.
[출처] http://crystalpark.tistory.com/12