Spring Framework는 기본적으로 어플리케이션의 비즈니스 서비스를 구동시키고 관리하는 Spring Container와
이러한 Container에 의해 관리되는 Bean으로 구성된다.
Bean은 Container를 통해서 인스턴스화되는 객체이며 Container에 의해 다른 Bean들과 Wiring(엮기)되고 관리된다.
Container
Spring IoC Container는 다음 두 가지 유형의 Container를 제공한다.
BeanFactory
| 설 명 |
|
Bean의 생성과 소멸 담당
|
|
Bean 생성 시 필요한 속성 설정
|
|
Bean의 Life Cycle에 관련된 메소드 호출
|
|
다수의 BeanFactory 인터페이스 구현 클래스를 제공하며 이중 가장 유용한 것은 XmlBeanFactory임
|
ApplicationContext
| 설 명 |
|
BeanFactory의 모든 기능 제공
|
|
ResourceBundle 파일을 이용한 국제화(I18N) 지원
|
|
다양한 Resource 로딩 방법 제공
|
|
이벤트 핸들링
|
|
Context 시작 시 모든 Singleton Bean을 미리 로딩(preloading) 시킴->? 초기에 설정 및 환경에 대한 에러 발견 가능함
|
|
다수의 ApplicationContext 구현 클래스 제공(XmlWebApplicationContext,FileSystemXmlApplicationContext,ClassPathXmlApplicationContext)
|
org.springframework.beans 와
org.springframework.context 패키지가 Spring Framework의
IoC Container를 위한 기본을 제공한다. BeanFactory는 객체를 관리하는
고급 설정 기법을 제공하고 ApplicationContext는 Spring의 AOP기능, 메시지
자원 핸들링, 이벤트 위임, 웹 어플리케이션에서 사용하기 위한
WebApplicationContext와 같은 특정 ApplicationContext 통합과 같은
기능을 추가 제공한다.
즉, BeanFactory가 설정 프레임워크와 기본
기능을 제공하는 반면 ApplicationContext는 BeanFactory의 모든 기능 뿐
아니라 전사적 중심의 기능이 추가되어 있다. ApplicationContext가 제공하는 부가
기능과는 별개로, ApplicationContext와 BeanFactory의 또 다른 차이점은
Singleton Bean을 로딩하는 방법에 있다. BeanFactory는 getBean()
메소드가 호출될 때까지 Bean의 생성을 미룬다. 즉 BeanFactory는 모든 Bean을
늦게 로딩(Lazy loading)한다. ApplicationContext는 Context를 시작시킬 때
모든 Singleton Bean을 미리 로딩함으로써, 그 Bean이 필요할 때 즉시 사용될 수
있도록 보장해준다. 즉, 어플리케이션 동작 시 Bean이 생성되기를 기다릴 필요가 없게 된다.
BeanFactory
Bean을 포함하고 관리하는 책임을 지는 Spring IoC Container의 실제
표현이다.가장 공통적으로 사용되는 BeanFactory의 구현체인
XmlBeanFactory 클래스는 XML 형태로 어플리케이션과 객체간의 참조 관계를
조합하는 객체를 정의함으로써 XML 설정 메타데이터를 기반으로 완전히 설정된 시스템이나
어플리케이션을 생성한다.
또한 아래의 예와 같이 XmlBeanFactory는 XML 파일에 기술되어 있는 정의를
바탕으로 Bean을 Loading해준다. (생성자에
org.springframework.core.io.Resource타입의 객체 넘겨줌)
BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));
org.springframework.beans.factory.BeanFactory인터페이스에
관한 API는
여기
를 참고한다.
| Resource Implementation |
Purpose |
| org.springframework.core.io.ByteArrayResource |
Defines a resource whose content is given by an array of bytes
|
| org.springframework.core.io.ClassPathResource |
Defines a resource that is to be retrieved from the classpath
|
| org.springframework.core.io.DescriptiveResource |
Defines a resource that holds a resource description but no actual readable resource
|
| org.springframework.core.io.FileSystemResource |
Defines a resource that is to be retrieved from the file system
|
| org.springframework.core.io.InputStreamResource |
Defines a resource that is to be retrieved from an input stream |
| org.springframework.web.portlet.context.PortletContextResource |
Defines a resource that is available in a portlet context
|
| org.springframework.web.context.support.ServletContextResource |
Defines a resource that is available in a servlet context
|
| org.springframework.core.io.UrlResource |
Defines a resource that is to be retrieved from a given URL
|
ApplicationContext
다음은 org.springframework.context.ApplicationContext
인터페이스의 대략적인 구조이다.

자주 사용되는 ApplicationContext의 구현 클래스는 아래와 같다.
-
XmlWebApplicationContext - 웹 기반의 Spring
어플리케이션을 작성할 때 내부적으로 사용
-
FileSystemXmlApplicationContext - 파일
시스템에 위치한 XML 설정 파일을 읽어들이는
ApplicationContext
-
ClassPathXmlApplicationContext - 클래스 패스에
위치한 XML 설정 파일을 읽어들이는 ApplicationContext
ApplicationContext 구현 클래스를 아래와 같이 사용할 수 있다.
ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml”);
ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml”);
설정 메타데이터
Container에 의해 "인스턴스화, 설정, 그리고 조합[어플리케이션내 객체를]"하기 위한
설정 방법에 대해 알아 보기로 하자. 대부분은 간단하고 직관적인 XML 형태로 제공되며 XML 기반의 설정
메타데이터를 사용하여 Bean을 정의하도록 한다. 다음은 XML 기반의 설정
메타데이터의 기본 구조 예제이다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here... -->
</beans>
XML 기반의 메타데이터 정의는 설정 메타데이터의 가장 많이 사용되는 형태이다. XML 외에 Java Properties 파일을 이용하거나
프로그램으로 처리(Spring의 Public API를 사용하여)함으로써, 설정 메타데이터를 제공할 수 있다.
Spring IoC Container 자체는 설정 메타데이터의 형태로부터 분리될 수 있기 때문이다.
Spring IoC Container 인스턴스화 시키는 예제
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) context;
XML 기반 설정 메타데이터 조합
XML 기반 설정 메타데이터는 다중 XML파일로 분리하여 정의할 수
있다. 여기서 주의할 점은 <import/>를 import를 수행하는
파일에서 <bean/> 이전에 두어야만 하는 것이다.
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
위의 예제에서 외부 Bean정의는 3개의 파일(services.xml,
messageSource.xml, 과 themeSource.xml)로부터 로드된다.
모든 위치 경로는 import를 수행하는 XML 파일에 상대적이다. 그래서 이 경우에
messageSource.xml 과 themeSource.xml이 import 대상 XML 파일의
위치 아래의 resources 에 두어야 하는 반면에 services.xml은
import를 수행하는 파일과 같은 디렉토리나 클래스패스 경로 내에 두어야만 한다. 이
예제처럼 /는 실제로 무시된다. import된 파일의 내용은
<beans/>를 가장 상위 레벨에 포함하는 스키마나 DTD에 따라
완전히 유효한 XML Bean 정의 파일이어야만 한다.
Beans
Bean
Spring IoC Container에 의해 관리되는 객체로 Container에 제공된 설정
메타데이터 내 정의(대개 XML <bean/> 형태로)에 의해 생성되며 실제로 아래 표로
나타낸 주요 메타데이터 정보를 포함하는 BeanDefinition 객체로 표현한다.
| 주요 메타데이터 속성 |
설 명 |
| id |
Bean의 구분을 위한 정보로 해당 bean에 접근하기 위한 Key임
|
| class |
정의된 Bean의 실제 구현클래스로 항상 full name으로 작성
|
| scope |
정의된 Bean의 인스턴스 생성 유형 정의. singleton, prototype,
request, session, globalSession 중 선택. Default는 singleton이며,
보다 자세한 Bean Scope에 대해서는 본 매뉴얼의 Spring >> IoC >> Extensions의 Bean Scope
을
참고하도록 한다.
|
| init-method |
해당 bean이 초기화된 후 context에 저장되기 전 호출되는 초기화
메소드 정의
|
| destroy-method |
해당 bean 제거 시 호출되는 메소드 정의 |
| factory-method |
해당 bean 생성 시 생성자를 사용하지 않고 특정 factory
method를 호출하여 생성 시 정의
|
| lazy-init |
true/false 값을 가지며 해당 bean이 호출되기 전에 초기화
시킬지 여부를 결정함. Default는 false이며 true인 경우,
해당 bean이 호출되는 시점에 초기화됨
|
Bean 명명하기
Bean 정의 시 Bean들을 구분하기 위해 'id' 혹은 'name' 속성을 사용하는데
'id'를 사용하는 경우, 하나의 Bean은 Container내에서 Unique한 id를
가지도록 한다. 일반적으로 Bean을 명명할때 인스턴스 필드명에 대한 표준 Java 규칙을
사용한다. Bean 이름은 소문자로 시작하고 camel-cased(첫 번째 단어는 소문자로 시작하고
두 번째 단어는 대문자로 시작)된다. 이러한 이름의 예제는 ‘accountService',
'userDao', 'loginController' 등이다. Bean을 명명하는 일관적인
방법을 적용하는 것은 설정을 좀 더 읽기 쉽고 이해하기 쉽도록 만들어준다. 이러한 명명표준을
적용하는 것은 어려운 일이 아니다. Spring AOP를 사용한다면 특정 Bean 이름과 관련된 Bean의
세트에 advice를 적용할 때 용이해질 수 있다.
Bean 인스턴스화
생성자를 이용한 인스턴스화
특정 인터페이스를 구현하거나 특정 형태로 코딩 할 필요가 없다.
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
static factory 메소드를 사용한 인스턴스화
Bean 객체가 factory 메소드를 호출하여 생성되는 것으로, 반환 객체의 타입을 명시하지 않고 factory 메소드를 포함하는 클래스를 정의하고 있음에 주의한다.
아래 예제에서 createInstance() 메소드는 static 메소드이어야 한다.
<bean id="exampleBean" class="examples.ExampleBean2" factory-method="createInstance"/>
인스턴스 factory 메소드를 사용한 인스턴스화
'class' 속성을 정의하지 않고 'factory-bean' 속성에 factory메소드를 포함하는 Bean을 정의한다.
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="myFactoryBean" class="..."/>
<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="myFactoryBean"
factory-method="createInstance"/>