Hello.java

 

  1. package springbook.etc;

  2. public class Hello {
  3. private String name;
  4. private Printer printer;
  5. public String sayHello() {
  6. return "Hello " + name;
  7. }
  8. public void print() {
  9. this.printer.print(sayHello());
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public void setPrinter(Printer printer) {
  15. this.printer = printer;
  16. }
  17. }

 

Printer.java(인터페이스)

 

  1. package springbook.etc;

     

  2. public interface Printer {
  3. void print(String message);
  4. }

StringPrinter.java(인터페이스 Printer.java 구현체)

 

 

  1. package springbook.etc;

  2. public class StringPrinter implements Printer {
  3. private StringBuffer buffer = new StringBuffer();
  4. public void print(String message) {
  5. this.buffer.append(message);
  6. }
  7. public String toString() {
  8. return this.buffer.toString();
  9. }
  10. }

 

TestHello.java(DI 정보 테스트)

 

  1. package springbook.etc;
  2.  
  3. import org.junit.Test;
  4. import static org.junit.Assert.*;
  5. import static org.hamcrest.CoreMatchers.*;
  6.  
  7. import org.springframework.beans.factory.config.BeanDefinition;
  8. import org.springframework.beans.factory.config.RuntimeBeanReference;
  9. import org.springframework.beans.factory.support.RootBeanDefinition;
  10. import org.springframework.context.support.StaticApplicationContext;

  11. public class TestHello {
  12. @Test
  13. public void testHelloBean() {
  14. //IoC 컨테이너 생성. 생성과 동시에 컨테이너로 동작한다.
  15. StaticApplicationContext ac = new StaticApplicationContext();
  16. //Hello 클래스를 hello1이라는 이름의 싱글톤 빈으로 컨테이너에 등록한다.
  17. ac.registerSingleton("hello1", Hello.class);
  18. //IoC 컨테이너가 등록한 빈을ㄹ 생성했는지 확인하기 위해 빈을 요청하고 Null이 아닌지 확
  19. Hello hello1 = ac.getBean("hello1", Hello.class);
  20. assertThat(hello1, is(notNullValue()));
  21. //빈 메타정보를 담은 오브젝트를 만든다. 빈 클래스는 Hello로 지정한다.
  22. //<bean class="springbook.etc.Hello" />에 해당하는 메타정
  23. BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
  24. //빈의 name프로퍼티에 들어갈 값을 지정한다.
  25. //<property name="name" value="Spring" />에 해당한다.
  26. helloDef.getPropertyValues().addPropertyValue("name", "Spring");
  27. //앞에서 생성한 빈 메타정보를 hello2라는 이름을 가진 빈으로 해서 등록흔다.
  28. //<bean id="hello2" /> 에 해당한다.
  29. ac.registerBeanDefinition("hello2", helloDef);
  30. //BeanDefinition으로 등록된 빈이 컨테이너에 의해 만들어지고 프로퍼티에 설정이 됐는지 확인한다.
  31. Hello hello2 = ac.getBean("hello2", Hello.class);
  32. assertThat(hello2.sayHello(), is("Hello Spring"));
  33. //처음 등록한 빈과 두 번쨰 등록한 빈이 별개의 오브젝트임을 확인
  34. assertThat(hello1, is(not(hello2)));
  35. assertThat(ac.getBeanFactory().getBeanDefinitionCount(), is(2));
  36. }
  37. @Test
  38. public void registerBeanWithDependency() {
  39. StaticApplicationContext ac = new StaticApplicationContext();
  40. //StringPrinter 타입이며, printer라는 이름을 가진 빈을 등록한다.
  41. ac.registerBeanDefinition("printer", new RootBeanDefinition(StringPrinter.class));
  42. BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
  43. helloDef.getPropertyValues().addPropertyValue("name", "Spring"); // 
  44. helloDef.getPropertyValues().addPropertyValue("printer", new RuntimeBeanReference("printer"));
  45. ac.registerBeanDefinition("hello", helloDef);
  46. Hello hello = ac.getBean("hello", Hello.class);
  47. hello.print();
  48. assertThat(ac.getBean("printer").toString(), is("Hello Spring"));
  49. }
  50. }
  51.  
IoC 컨테이너가 POJO 클래스와설정 메타정보를 이용해 어떻게 최종사용할 애플리케이션 런타임 오브젝트를 만들어내는 지 이해할 수 있을 것이다. 이렇게 애플리케이션을 구성하는 빈 오브젝트를 생성하는 것이 IoC 컨테이너의 핵심이다. IoC 컨테이너는 일단 빈 오브젝트가 생성되고 관계가 만들어지면 그 뒤로는 거의 관여하지 않는다. 기본적으로 싱글톤 빈은 애플리케이션 컨텍스트의 초기화 작업 중에 모두 만들어진다.

 

 

이 글은 스프링노트에서 작성되었습니다.

토비의스프링3
카테고리 컴퓨터/IT > 프로그래밍/언어 > 프로그래밍일반
지은이 이일민 (에이콘출판, 2010년)
상세보기

1. 소프트웨어 개발에서 절대로 바뀌지 않는 것은 없기 때문이다.
클래스 대신 인터페이스를 사용하고, new 를 이용해 생성하는 대신 DI를 통해 주입받게 하는 건 아주 단순하고 쉬운 작업이다.
2. 클래스의 구현 방식은 바뀌지 않는다고 하더라도 인터페이스를 두고 DI를 적용하게 해두면 다른 차원의 서비스 기능을 도입할 수 있기 때문이다.

3. 테스트 때문이다.  
단지 효율적인 테스트를 손쉽게 만들기 위해서라도 DI를 적용해야 한다. 그러기 위해서는 가능한 한 작은 단위의 대상에 국한해서 테스트 해야한다.  

+ Recent posts