Container Overview(한글)
org.springframework.context.ApplicationContext
인터페이스는 Spring IoC 컨테이너를 나타내며 Bean의 인스턴스화, 구성 및 어셈블리를 담당합니다.
컨테이너는 구성 메타데이터를 읽음으로써 인스턴스화, 구성 및 어셈블할 객체에 대한 지침을 얻습니다.
구성 메타데이터는 XML, Java 어노테이션 또는 Java 코드로 표현됩니다.
이를 통해 애플리케이션을 구성하는 객체와 이러한 객체 간의 풍부한 상호 의존성을 표현할 수 있습니다.
ApplicationContext
인터페이스의 여러 구현이 Spring과 함께 제공됩니다.
독립형 애플리케이션에서는 ClassPathXmlApplicationContext
또는 FileSystemXmlApplicationContext
인스턴스를 생성하는 것이 일반적입니다.
XML은 구성 메타데이터를 정의하는 전통적인 형식이었지만, 이러한 추가 메타데이터 형식을 선언적으로 지원하도록 약간의 XML 구성을 제공하여 컨테이너에 Java 주석이나 코드를 메타데이터 형식으로 사용하도록 지시할 수 있습니다.
대부분의 애플리케이션 시나리오에서는 하나 이상의 Spring IoC 컨테이너 인스턴스를 인스턴스화하는 데 명시적인 사용자 코드가 필요하지 않습니다.
예를 들어, 웹 애플리케이션 시나리오에서는 일반적으로 애플리케이션의 web.xml
파일에 8줄 정도의 간단한 상용구 웹 설명자 XML로 충분합니다(다음을 참조 Convenient ApplicationContext Instantiation for Web Applications). Spring Tools for Eclipse를 사용하는 경우(Eclipse 기반 개발 환경), 몇 번의 마우스 클릭이나 키 입력으로 이 상용구 구성을 쉽게 생성할 수 있습니다.
다음 다이어그램은 Spring이 어떻게 작동하는지에 대한 개략적인 보기를 보여줍니다. 애플리케이션 클래스는 구성 메타데이터와 결합되어 'ApplicationContext' 가 생성되고 초기화되면 완전히 구성되고 실행 가능한 시스템 또는 애플리케이션을 갖게 됩니다.

구성 메타데이터(Configuration Metadata)
앞의 다이어그램에서 볼 수 있듯이 Spring IoC 컨테이너는 일종의 구성 메타데이터를 사용합니다. 이 구성 메타데이터는 애플리케이션 개발자가 애플리케이션의 객체를 인스턴스화, 구성 및 어셈블하도록 Spring 컨테이너에 지시하는 방법을 나타냅니다.
구성 메타데이터는 전통적으로 간단하고 직관적인 XML 형식으로 제공되며, 이 장에서는 대부분 Spring IoC 컨테이너의 주요 개념과 기능을 전달하기 위해 이 형식을 사용합니다.
XML 기반 메타데이터만이 구성 메타데이터의 유일한 허용 형식은 아닙니다. Spring IoC 컨테이너 자체는 이 구성 메타데이터가 실제로 작성되는 형식과 완전히 분리되어 있습니다. 요즘에는 많은 개발자들이 Spring 애플리케이션을 위해 Java 기반 구성을 선택합니다. |
Spring 컨테이너와 함께 다른 형태의 메타데이터를 사용하는 방법에 대한 자세한 내용은 다음을 참조하세요:
-
어노테이션 기반 구성: 어노테이션 기반 구성 메타데이터를 사용하여 Bean을 정의합니다.
-
Java 기반 구성: XML 파일이 아닌 Java를 사용하여 애플리케이션 클래스 외부에 Bean을 정의합니다. 자세한 내용은 다음을 참조하세요:
@Configuration
,@Bean
,@Import
,@DependsOn
어노테이션.
스프링 구성은 컨테이너가 관리해야 하는 최소 하나 이상의 Bean 정의로 구성됩니다.
XML 기반 구성 메타데이터는 이러한 Bean을 최상위 <beans/>
요소 내부의 <bean/>
요소로 구성합니다.
Java 구성은 일반적으로 @Configuration
클래스 내에서 @Bean
주석이 달린 메서드를 사용합니다.
이러한 Bean 정의는 애플리케이션을 구성하는 실제 객체에 해당합니다.
일반적으로 서비스 계층 객체, 리포지토리 또는 DAO(데이터 액세스 객체)와 같은 지속성 계층 객체, 웹 컨트롤러와 같은 프레젠테이션 객체, JPA EntityManagerFactory
, JMS 큐와 같은 인프라 객체 등을 정의합니다.
일반적으로 도메인 개체를 만들고 로드하는 것은 리포지토리와 비즈니스 로직의 책임이기 때문에 일반적으로 컨테이너에서 세분화된 도메인 개체를 구성하지 않습니다.
다음 예는 XML 기반 구성 메타데이터의 기본 구조를 보여줍니다:
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="..."> (1) (2)
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
1 | id 속성은 개별 Bean 정의를 식별하는 문자열입니다. |
2 | class 속성은 Bean의 유형을 정의하며 정규화된 클래스 이름을 사용합니다. |
id
속성의 값은 협업 객체를 참조하는 데 사용할 수 있습니다.
이 예에서는 협업 객체를 참조하기 위한 XML은 표시되지 않습니다.
자세한 내용은 Dependencies를 참조하세요.
컨테이너 인스턴스화(Instantiating a Container)
ApplicationContext
생성자에 제공된 위치 경로는 컨테이너가 로컬 파일 시스템, Java CLASSPATH
등과 같은 다양한 외부 리소스에서 구성 메타데이터를 로드할 수 있도록 하는 리소스 문자열입니다.
-
Java
-
Kotlin
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
Spring의 IoC 컨테이너에 대해 배운 후에는 URI 구문에 정의된 위치에서 InputStream을 읽기 위한 편리한 메커니즘을 제공하는 Spring의 |
다음 예시는 서비스 계층 객체 (services.xml)
구성 파일을 보여줍니다:
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans>
다음 예는 데이터 액세스 개체 daos.xml
파일을 보여줍니다:
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao"
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for data access objects go here -->
</beans>
앞의 예제에서 서비스 계층은 PetStoreServiceImpl
클래스와 (JPA 객체-관계형 매핑 표준에 기반한) JpaAccountDao
및 JpaItemDao
유형의 데이터 액세스 객체 두 개로 구성됩니다.
property name
요소는 JavaBean 속성의 이름을 참조하고 ref
요소는 다른 Bean 정의의 이름을 참조합니다.
이러한 id`와 `ref
요소 간의 연결은 협업하는 객체 간의 종속성을 나타냅니다.
객체의 종속성 구성에 대한 자세한 내용은 Dependencies를 참조하세요.
XML 기반 구성 메타데이터 작성하기(Composing XML-based Configuration Metadata)
Bean 정의가 여러 XML 파일에 걸쳐 있으면 유용할 수 있습니다. 종종 각 개별 XML 구성 파일은 아키텍처에서 논리 계층 또는 모듈을 나타냅니다.
애플리케이션 컨텍스트 생성자를 사용하여 이러한 모든 XML 조각에서 Bean 정의를 로드할 수 있습니다.
이 생성자는 이전 섹션에 표시된 것처럼 여러 개의 Resource
위치를 사용합니다. 또는 <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 정의가 세 개의 파일에서 로드됩니다:
services.xml
, messageSource.xml
, themeSource.xml
입니다.
모든 위치 경로는 가져오기를 수행하는 정의 파일에 상대적이므로 services.xml`은 가져오기를 수행하는 파일과 동일한 디렉토리 또는 클래스 경로 위치에 있어야 하며, `messageSource.xml
및 themeSource.xml
은 가져오는 파일 위치 아래의 resources
위치에 있어야 합니다.
보시다시피 선행 슬래시는 무시됩니다.
그러나 이러한 경로는 상대적이기 때문에 슬래시를 전혀 사용하지 않는 것이 좋습니다.
최상위 <beans/>
요소를 포함하여 가져오는 파일의 내용은 Spring 스키마에 따라 유효한 XML Bean 정의여야 합니다.
상대 "../" 경로를 사용하여 상위 디렉터리의 파일을 참조하는 것은 가능하지만 권장되지는 않습니다.
이렇게 하면 현재 애플리케이션 외부에 있는 파일에 대한 종속성이 생성됩니다.
특히 런타임 확인 프로세스가 “가장 가까운” 클래스 경로 루트를 선택한 다음 해당 상위 디렉터리를 조사하는 상대 경로 대신 항상 정규화된 리소스 위치를 사용할 수 있습니다(예: |
네임스페이스 자체에서 가져오기 지시어 기능을 제공합니다.
일반 Bean 정의 이외의 추가 구성 기능은 Spring에서 제공하는 다양한 XML 네임스페이스에서 사용할 수 있습니다. — 예를 들어, context
및 util
네임스페이스가 있습니다.
The Groovy Bean Definition DSL(번역 제외, 사유:그루비)
As a further example for externalized configuration metadata, bean definitions can also be expressed in Spring’s Groovy Bean Definition DSL, as known from the Grails framework. Typically, such configuration live in a ".groovy" file with the structure shown in the following example:
beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
settings = [mynew:"setting"]
}
sessionFactory(SessionFactory) {
dataSource = dataSource
}
myService(MyService) {
nestedBean = { AnotherBean bean ->
dataSource = dataSource
}
}
}
This configuration style is largely equivalent to XML bean definitions and even
supports Spring’s XML configuration namespaces. It also allows for importing XML
bean definition files through an importBeans
directive.
컨테이너 사용(Using the Container)
ApplicationContext’는 다양한 Bean과 그 종속성의 레지스트리를 유지 관리할 수 있는 고급 팩토리를 위한 인터페이스입니다. `T getBean(String name, Class<T> requiredType)
, 메서드를 사용하여 Bean의 인스턴스를 검색할 수 있습니다.
`ApplicationContext`를 사용하면 다음과 같이 Bean 정의를 읽고 액세스할 수 있습니다. 예제에서 볼 수 있습니다:
-
Java
-
Kotlin
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();
import org.springframework.beans.factory.getBean
// create and configure beans
val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
// retrieve configured instance
val service = context.getBean<PetStoreService>("petStore")
// use configured instance
var userList = service.getUsernameList()
그루비 구성을 사용하면 부트스트랩은 매우 비슷해 보입니다. 하지만 Groovy를 인식하는 다른 컨텍스트 구현 클래스가 있습니다(XML Bean 정의도 이해). 다음 예제는 Groovy 구성을 보여줍니다:
-
Java
-
Kotlin
ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
val context = GenericGroovyApplicationContext("services.groovy", "daos.groovy")
가장 유연한 변형은 reader delegates(역자설명 : 프로세스를 처리하는 행위를 자신이 처리하는게 아닌 대신 해줄 함수나 클래스에게 처리를 맡기는 패턴)와 결합된 GenericApplicationContext
입니다. — 예를 들어, 다음과 같이 XML 파일의 경우 XmlBeanDefinitionReader
와 함께 사용하는 것입니다.
예제에서 볼 수 있습니다:
-
Java
-
Kotlin
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
val context = GenericApplicationContext()
XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml")
context.refresh()
다음과 같이 Groovy 파일에 대해 GroovyBeanDefinitionReader
를 사용할 수도 있습니다.
예제에서 볼 수 있습니다:
-
Java
-
Kotlin
GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();
val context = GenericApplicationContext()
GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy")
context.refresh()
이러한 reader delegates를 동일한 ApplicationContext
에서 혼합하여 다양한 구성 소스에서 Bean 정의를 읽을 수 있습니다.
그런 다음 getBean
을 사용하여 Bean의 인스턴스를 검색할 수 있습니다.
ApplicationContext
인터페이스에는 Bean을 검색하기 위한 몇 가지 다른 메서드가 있지만, 이상적으로는 애플리케이션 코드에서 이러한 메서드를 사용하지 않아야 합니다.
실제로 애플리케이션 코드에는 getBean()
메서드에 대한 호출이 전혀 없어야 하며, 따라서 Spring API에 대한 종속성이 전혀 없어야 합니다.
예를 들어, Spring과 웹 프레임워크의 통합은 컨트롤러 및 JSF 관리 Bean과 같은 다양한 웹 프레임워크 구성 요소에 대한 의존성 주입을 제공하여 메타데이터(예: @autowiring 어노테이션)를 통해 특정 Bean에 대한 의존성을 선언할 수 있게 해줍니다.