본문 바로가기

Spring

스프링3.1 vol2 - IoC 컨테이너 : 빈 팩토리와 애플리케이션 컨텍스트

ApplicationContext를 구현한 클래스의 인스턴스를 만들어 IoC컨테이너를 간단하게 구현해 볼 수 있다.

StaticApplicationContext ctx = new StaticApplicationContext();

이 컨테이너가 본격적인 IoC컨테이너가 되기 위해선 POJO클래스와 설정 메타정보가 필요하다.

POJO란 Plain Old Java Object의 약자로, 특정 기술과 스펙에서 독립적인 일반적 Java Object를 의미한다.

스프링의 핵심적인 특징 중 하나라고 생각한다.
특정 스펙에 종속되지 않은 일반 자바 오브젝트를 사용함으로써 객체지향의 특징을 가장 잘 살릴 수 있다.

설정 메타정보란 POJO를 빈으로 등록할 것인지, 등록한다면 어떻게 등록하고 어떻게 동작하게 할 것인지를 의미한다.

스프링이 사용하는 메타정보란 BeanDefinition 인터페이스를 구현한 클래스를 의미한다.
우리가 작성한 설정파일은 BeanDefinitionReader 인터페이스를 구현한 리더기에 의해 BeanDefinition 오브젝트들의 묶음으로 변환되고,
스프링은 그 정보를 사용하여 오브젝트를 관리한다.
즉, 설정파일의 포맷에 맞는 BeanDefinitionReader만 있다면 설정파일은 어떠한 포맷으로도 작성될 수 있다.

빈 메타정보

빈 아이디, 이름, 별칭
클래스 정보
스코프(싱글톤, 프로토타입 등)
프로퍼티
생성자
지연로딩/우선 빈/자동 와이어링/부모 빈 등의 정보

이런 메타정보를 통해 빈을 생성하고, 프로퍼티나 생성자를 통해 관계를 형성한다(DI)

스프링 어플리케이션은 결국 POJO와 설정 메타정보를 이용해 IoC컨테이너가 만들어주는 오브젝트의 조합이다.

어플리케이션 컨텍스트에 빈 등록하기

StaticApplicationContext ctx = new StaticApplicationContext();
ctx.registerSingleton("person", Person.class);

빈은 클래스단위가 아니라 오브젝트 단위기 때문에 동일한 클래스를 여러개의 빈으로 등록 가능하다.
이는 빈마다 다른 설정을 지정해두고 사용하기 위해서다.

어플리케이션 컨텍스트에 BeanDefinition 등록하기

StaticApplicationContext ctx = new StaticApplicationContext();

// bean definition으로 등록
BeanDefinition personDef1 = new RootBeanDefinition(Person.class);
personDef1.getPropertyValues().addPropertyValue("name","name1");
ctx.registerBeanDefinition("person1", personDef1);

ctx.registerBeanDefinition("address", new RootBeanDefinition(Address.class)); // DI할 Bean

BeanDefinition personDef2 = new RootBeanDefinition(Person.class);
personDef2.getPropertyValues().addPropertyValue("name","name2");
personDef2.getPropertyValues().addPropertyValue("address", new RuntimeBeanReference("address")); // DI
ctx.registerBeanDefinition("person2", personDef2);

이를 xml 설정파일로 작성한다면

<bean id="person1" class="com.joont.Person">
    <property name="name" value="name1" />
</bean>

<bean id="address" class="com.joont.Address" />

<bean id="person2" class="com.joont.Person">
    <property name="name" value="name2" />
    <property name="address" ref="address" />
</bean>

의 형태가 되겠다.