IoC 컨테이너 : 빈 팩토리와 애플리케이션 컨텍스트
IoC 컨테이너 = 빈 팩토리 또는 애플리케이션 컨텍스트
- 빈 팩토리 : 객체의 생성과 객체 사이의 런타임 관계를 설정하는 DI 시점에서는 빈팩토리라 함
- 애플리케이션 컨텍스트 : 앤터프라이즈 애플리케이션을 개발하는데 필요한 몇가지 기능이 추가된 것
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
스프링 컨테이너는 ApplicationContext 인터페이스의 구현체이다. 이 인터페이스를 보면 BeanFactory를 상속받은 것을 확인할 수 있다.
IoC 컨테이너를 이용해 애플리케이션 만들기
// Ioc 컨테이너 생성, 생성과 동시에 컨테이너로 동작한다.
StaticApplicationContext ac = new StaticApplicationContext();
// Ioc 컨테이너 생성, 생성과 동시에 컨테이너로 동작한다.
StaticApplicationContext ac = new StaticApplicationContext();
이로써 IoC 컨테이너가 준비되었지만 아무일을 하지 않는 빈 컨테이너일 뿐이다. POJO 클래스와 설정 메타정보가 더 필요하다.
IoC 컨테이너 사용하기 위해 필요한 것 - 1. POJO클래스
public class Hello {
private String name;
private Printer printer;
public String sayHello() {
return "Hello " + name;
}
/**
* 1. 구체적으로 어떤 방식으로 출력할지는 몰라도 됨.
* Printer interface를 사이에 두고 느슨하게 연결되어 있음
* => 출력 방식이 변경되어도 Hello 객체
* 수정하지 않아도 됨 2. IoC 컨테이너가 실제 Printer 구현체와 연결해 준다.
*/
public void print() {
this.printer.print(sayHello());
}
public void setName(String name) {
this.name = name;
}
/**
* Printer 인터페이스 구현체를 DI 받는다.
* @param printer
*/
public void setPrinter(Printer printer) {
this.printer = printer;
}
}
위와 같이 각자 기능에 충실하게 독립적으로 POJO 클래스를 만들고, 인터페이스를 이용하여 결합도를 낮추는 것까지가 IoC 컨테이너가 사용할 POJO를 준비하는 첫번째 단계이다.
IoC 컨테이너 사용하기 위해 필요한 것 - 2. 설정 메타정보
스프링 설정 메타정보는 어떠한 형태로 지정해도 상관없다? 왜?
- 빈 아이디, 이름, 별칭 : 빈 오브젝트를 구분할 수 있는 식별자
- 클래스 또는 클래스 이름 : 빈으로 만들 POJO 클래스 또는 서비스 클래스 정보
- 스코프 : 싱글톤, 프로토타입과 같은 빈의 생성 방식과 존재 범위
- 프로터피 값 또는 참조 : DI에 사용할 프로퍼티 이름과 값 또는 참조하는 빈의 이름
- 생성자 파라미터 값 또는 참조 : DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름
- 지연된 로딩 여부, 우선 빈 여부, 자동와이어링 여부, 부모 빈 정보, 빈팩토리 이름 등
스프링 애플리케이션 = POJO 클래스 + 설정 메타정보를 이용해 IoC 컨테이너가 만들어주는 오브젝트의 조합
@Test
public void registerBean() {
// Ioc 컨테이너 생성, 생성과 동시에 컨테이너로 동작한다.// StaticApplicationContext는 테스트용으로 사용하기에 적당하다.
StaticApplicationContext ac = new StaticApplicationContext();
// Hello 클래스를 hello1이라는 이름의 싱글톤 빈으로 컨테이너에 등록한다.
ac.registerSingleton("hello1", Hello.class);
// IoC 컨테니어가 등록한 빈을 생성했는지 확인하기 위해 빈을 요청
Hello hello1 = ac.getBean("hello1", Hello.class);
assertThat(hello1, is(notNullValue()));
}
직접 BeanDefinition 타입의 설정 메타정보를 만들어서 IoC 컨테이너에 등록해보기
BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
helloDef.getPropertyValues().addPropertyValue("name", "Spring");
ac.registerBeanDefinition("hello2", helloDef);
@Test
public void register_with_beanDefinition() {
// Ioc 컨테이너 생성, 생성과 동시에 컨테이너로 동작한다.
StaticApplicationContext ac = new StaticApplicationContext();
BeanDefinition helloDef = new RootBeanDefinition(Hello.class);
// ConsolePrinter 클래스 타입이며 printer 이름을 가진 빈 등록
ac.registerBeanDefinition("printer", new RootBeanDefinition(ConsolePrinter.class));
// 빈에 대한 프로퍼티 등록
helloDef.getPropertyValues().addPropertyValue("name", "Spring");
helloDef.getPropertyValues().addPropertyValue("printer", new RuntimeBeanReference("printer"));
ac.registerBeanDefinition("hello2", helloDef);
Hello hello2 = ac.getBean("hello2", Hello.class);
assertThat(hello2.sayHello(), is("Hello Spring"));
assertThat(ac.getBeanFactory().getBeanDefinitionCount(), is(2));
hello2.print();
}
이제 IoC 컨테이너가 POJO클래스와 설정 메타정보를 이용해 어떻게 최종 사용할 애플리케이션 런타임 오브젝트를 만들어내는지 이해할 수 있다. IoC 컨테이너는 빈 오브젝트가 생성되고 관계가 정의되면 그 뒤로는 거의 관여하지 않는다.
IoC 컨테이너의 종류와 사용 방법
StaticApplicationContext
GenericApplicationContext
GenericApplicationContext gac = new GenericApplicationContext();
XmlBeanDefinitionReader reader =new XmlBeanDefinitionReader(gac);
reader.loadBeanDefinitions("filelocation/context.xml");
ac.refresh(); // 모든 메타정보 등록 완료되었으니, 애플리케이션 컨테이너를 초기화하라는 명령
GenericXmlApplicationContxt
GenericXmlApplicationContext gxac= new GenericXmlApplicationContext("filelocation/context.xml");
WebApplicationContext
- 스프링 애플리케이션에서 가장 많이 사용되는 애플리케이션 컨텍스트(IoC 컨테이너)이다.
- 웹 환경에서 사용할 때 필요한 기능이 추가된 것 ( 대부분 서블릿 기반의 독립 WAR로 만들어짐 )
- 사용 방법을 이해하기 위해 IoC 컨테이너를 적용했을 때 애플리케이션을 기동시키는 방법에 대해 알아볼 필요가 있음
- 독립 자바 프로그램은 자바 VM에게 main() 메소드를 호출해달라 함
- But, 웹에서는 main 메소드를 호출할 수가 없다. 사용자가 여럿이며 동시에 웹 어플리케이션을 사용한다.
=> 서블릿 컨테이너가 브라우저로부터 오는 HTTP 요청을 받아서 해당 요청에 매핑되는 서블릿을 실행해주는 방식으로 동작한다. ( 서블릿이 일종의 main 메소드 역할 )
웹 환경에서 스프링 애플리케이션이 기동하는 방식
- main() 메소드 역할을 하는 서블릿 만들기
- 미리 애플리케이션 컨텍스트 생성
- 요청이 서블릿으로 들어올때 마다 getBean()으로 필요한 빈을 가져옴
DispatchServlet
스프링에서 웹 환경에서 애플리케이션 컨텍스트를 생성하고 설정 메타 정보를 초기화해주고, 클러이언트로 들어오는 요청마다 적절한 빈을 만들어서 찾아서 이를 실행해주는 기능을 가진 DispatchServlet이라는 이름의 서블릿을 제공한다.
web.xml에만 이 서블릿을 등록해주면 웹 환경에서 스프링 컨테이너(IoC 컨테이너)가 만들어지고 애플리케이션을 실행할 수 있다.
'Back-End > 토비의 스프링3' 카테고리의 다른 글
1.3-IoC 컨테이너 : 프로토타입과 스코프 (3) | 2018.10.02 |
---|---|
1.2-IoC 컨테이너 : 빈 설정하기 (0) | 2018.09.22 |
스프링 공부방법 (0) | 2018.09.16 |
#6. AOP (0) | 2017.08.29 |
#5. 서비스 추상화 (0) | 2017.08.17 |