Loading...
Spring Framework Reference Documentation 7.0.2의 Container Overview의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
org.springframework.context.ApplicationContext 인터페이스는 Spring IoC
컨테이너를 나타내며 bean을 인스턴스화하고, 구성하고, 조립하는 책임을 집니다.
컨테이너는 인스턴스화하고, 구성하고, 조립해야 할 컴포넌트에 대한 지시를
설정 메타데이터를 읽어서 얻습니다.
설정 메타데이터는 어노테이션이 적용된 컴포넌트 클래스, 팩토리 메서드를 가진 설정 클래스, 또는 외부 XML 파일이나 Groovy 스크립트로 표현될 수 있습니다. 어느 형식을 사용하든, 애플리케이션과 그 컴포넌트들 사이의 풍부한 상호 의존성을 구성할 수 있습니다.
ApplicationContext 인터페이스의 여러 구현체가 core Spring의 일부입니다.
stand-alone 애플리케이션에서는
AnnotationConfigApplicationContext
또는 ClassPathXmlApplicationContext
인스턴스를 생성하는 것이 일반적입니다.
대부분의 애플리케이션 시나리오에서는 하나 이상의 Spring IoC 컨테이너 인스턴스를
생성하기 위해 명시적인 사용자 코드가 필요하지 않습니다. 예를 들어, 일반적인 web
애플리케이션 시나리오에서는 애플리케이션의 web.xml 파일에 있는 간단한 boilerplate
web descriptor XML만으로 충분합니다(see
Convenient ApplicationContext Instantiation for Web Applications).
Spring Boot 시나리오에서는 일반적인 설정 관례에 따라 애플리케이션 컨텍스트가 암묵적으로 bootstrap됩니다.
다음 다이어그램은 Spring이 동작하는 방식에 대한 상위 수준 view를 보여줍니다.
애플리케이션 클래스는 설정 메타데이터와 결합되어 ApplicationContext가
생성되고 초기화된 후 완전히 구성되고 실행 가능한 시스템 또는 애플리케이션을
갖게 됩니다.

Figure 1. The Spring IoC 컨테이너
앞의 다이어그램에서 보듯이 Spring IoC 컨테이너는 일종의 설정 메타데이터를 소비합니다. 이 설정 메타데이터는 애플리케이션 개발자인 여러분이 Spring 컨테이너에게 애플리케이션의 컴포넌트를 어떻게 인스턴스화하고, 구성하고, 조립할지를 알려주는 방식을 나타냅니다.
Spring IoC 컨테이너 자체는 이 설정 메타데이터가 실제로 어떤 형식으로 작성되는지에 완전히 decouple되어 있습니다. 요즘 많은 개발자가 Spring 애플리케이션에 대해 Java-based configuration을 선택합니다:
@Configuration,
@Bean,
@Import,
@DependsOn 어노테이션을 참조하십시오.Spring 설정은 컨테이너가 관리해야 하는 하나 이상의 bean definition으로
구성됩니다(일반적으로는 둘 이상). Java 설정은 보통 @Configuration 클래스
내의 @Bean 어노테이션이 적용된 메서드를 사용하며, 각각이 하나의 bean definition에
해당합니다.
이러한 bean definition은 애플리케이션을 구성하는 실제 객체에 해당합니다.
일반적으로 서비스 레이어 객체, repository나 data access object(DAO) 같은
persistence 레이어 객체, Web controller 같은 presentation 객체, JPA
EntityManagerFactory, JMS queue와 같은 infrastructure 객체를 정의합니다.
일반적으로 컨테이너에는 세밀한 domain 객체를 설정하지 않는데, 보통 repository와 business logic이 domain 객체를 생성하고 로드하는 책임을 지기 때문입니다.
XML 기반 설정 메타데이터는 top-level <beans/> element 내부의 <bean/>
element로 이러한 bean을 설정합니다. 다음 예제는 XML 기반 설정
메타데이터의 기본 구조를 보여줍니다:
1<?xml version="1.0" encoding="UTF-8"?> 2<beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 https://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="..." class="..."> (1) (2) 8 <!-- collaborators and configuration for this bean go here --> 9 </bean> 10 11 <bean id="..." class="..."> 12 <!-- collaborators and configuration for this bean go here --> 13 </bean> 14 15 <!-- more bean definitions go here --> 16 17</beans>
| 1 | id attribute는 개별 bean definition을 식별하는 string입니다. |
| 2 | class attribute는 bean의 type을 정의하며 fully qualified<br>class name을 사용합니다. |
id attribute의 값은 협력 객체를 참조하는 데 사용할 수 있습니다. 협력 객체를
참조하기 위한 XML은 이 예제에 표시되어 있지 않습니다. 자세한 내용은
Dependencies를 참조하십시오.
컨테이너를 인스턴스화하려면 XML resource 파일에 대한 location path를
ClassPathXmlApplicationContext constructor에 제공해야 하며, 이를 통해 컨테이너는
local file system, Java CLASSPATH 등 다양한 external resource에서 설정
메타데이터를 로드할 수 있습니다.
1ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
1val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
Spring의 IoC 컨테이너에 대해 학습한 후에는 Spring의
Resourceabstraction에 대해 더 알고 싶을 수 있습니다(이는 Resources에 설명되어 있습니다). 이는 URI syntax로 정의된 location에서 InputStream을 읽기 위한 편리한 메커니즘을 제공합니다. 특히Resourcepath는 Application Contexts and Resource Paths에 설명된 대로 애플리케이션 컨텍스트를 구성하는 데 사용됩니다.
다음 예제는 서비스 레이어 객체 (services.xml) 설정 파일을 보여줍니다:
1<?xml version="1.0" encoding="UTF-8"?> 2<beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 https://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <!-- services --> 8 9 <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> 10 <property name="accountDao" ref="accountDao"/> 11 <property name="itemDao" ref="itemDao"/> 12 <!-- additional collaborators and configuration for this bean go here --> 13 </bean> 14 15 <!-- more bean definitions for services go here --> 16 17</beans>
다음 예제는 data access object daos.xml 파일을 보여줍니다:
1<?xml version="1.0" encoding="UTF-8"?> 2<beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 https://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="accountDao" 8 class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao"> 9 <!-- additional collaborators and configuration for this bean go here --> 10 </bean> 11 12 <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao"> 13 <!-- additional collaborators and configuration for this bean go here --> 14 </bean> 15 16 <!-- more bean definitions for data access objects go here --> 17 18</beans>
앞의 예제에서 서비스 레이어는 PetStoreServiceImpl 클래스와
JpaAccountDao 및 JpaItemDao 타입의 두 data access object로 구성됩니다(JPA
Object-Relational Mapping standard 기반). property name element는 JavaBean
property의 이름을 나타내고, ref element는 다른 bean definition의 이름을
나타냅니다.
id element와 ref element 간의 이 연결은 협력 객체 사이의
dependency를 표현합니다. 객체의 dependency를 설정하는 방법에 대한
자세한 내용은 Dependencies를 참조하십시오.
bean definition이 여러 XML 파일에 걸쳐 있는 것이 유용할 수 있습니다. 종종 각 개별 XML 설정 파일은 architecture에서 논리적인 레이어나 모듈을 나타냅니다.
ClassPathXmlApplicationContext constructor를 사용하여 XML fragment에서 bean
definition을 로드할 수 있습니다. 이 constructor는
previous section에
나온 것처럼 여러 개의 Resource location을 인수로 받습니다.
또는 <import/>
element를 한 번 이상 사용하여 다른 파일에서 bean definition을 로드할 수 있습니다.
다음 예제는 그 방법을 보여줍니다:
1<beans> 2 <import resource="services.xml"/> 3 <import resource="resources/messageSource.xml"/> 4 5 <bean id="bean1" class="..."/> 6 <bean id="bean2" class="..."/> 7</beans>
앞의 예제에서 external bean definition은 services.xml 및 messageSource.xml
파일에서 로드됩니다. 모든 location path는 import를 수행하는 definition 파일을
기준으로 상대적이므로, services.xml은 import를 수행하는 파일과 동일한
directory나 classpath location에 있어야 하고, messageSource.xml은 import 파일의
location 아래의 resources location에 있어야 합니다.
보듯이 선행 slash는
무시됩니다. 그러나 이러한 path는 상대적이므로 slash를 전혀 사용하지 않는 것이 더
좋은 형태입니다. import되는 파일의 내용(최상위 <beans/> element 포함)은 Spring
Schema에 따라 유효한 XML bean definition이어야 합니다.
상대적인 "../" path를 사용하여 상위 directory의 파일을 참조하는 것도 가능하지만 권장되지 않습니다. 이렇게 하면 현재 애플리케이션 외부의 파일에 대한 dependency가 생깁니다. 특히 runtime resolution process가 “가장 가까운” classpath root를 선택한 다음 그 parent directory를 조회하는
classpath:URL(예:classpath:../services.xml)에 대해 이러한 참조는 권장되지 않습니다. classpath 설정 변경으로 인해 다른 잘못된 directory가 선택될 수 있습니다.
항상 상대 path 대신 완전한 resource location을 사용할 수 있습니다(예:
file:C:/config/services.xml또는classpath:/config/services.xml). 그러나 이렇게 하면 애플리케이션의 설정을 특정 absolute location에 결합하게 된다는 점을 인지해야 합니다. 일반적으로 이러한 absolute location에 대해 "${…}" placeholder를 사용하고 runtime에 JVM system property에 대해 resolve되도록 하는 등 간접 참조를 유지하는 것이 더 바람직합니다.
namespace 자체가 import directive 기능을 제공합니다. plain bean definition
이외의 추가 설정 기능은 Spring이 제공하는 여러 XML namespace에서
사용할 수 있습니다. 예를 들어 context 및 util namespace가 있습니다.
ApplicationContext는 다양한 bean과 그 dependency의 registry를 유지할 수 있는
고급 factory를 위한 인터페이스입니다. T getBean(String name, Class<T> requiredType)
메서드를 사용하여 bean 인스턴스를 가져올 수 있습니다.
다음 예제에서 보듯이 ApplicationContext는 bean definition을 읽고 이에 접근할 수
있게 해줍니다:
1// create and configure beans 2ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); 3 4// retrieve configured instance 5PetStoreService service = context.getBean("petStore", PetStoreService.class); 6 7// use configured instance 8List<String> userList = service.getUsernameList();
1import org.springframework.beans.factory.getBean 2 3// create and configure beans 4val context = ClassPathXmlApplicationContext("services.xml", "daos.xml") 5 6// retrieve configured instance 7val service = context.getBean<PetStoreService>("petStore") 8 9// use configured instance 10var userList = service.getUsernameList()
Groovy 설정을 사용하면 bootstrap 과정은 매우 비슷해집니다. Groovy를 인식하는 다른 context 구현 클래스를 사용하지만 XML bean definition도 이해합니다. 다음 예제는 Groovy 설정을 보여줍니다:
1ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
1val context = GenericGroovyApplicationContext("services.groovy", "daos.groovy")
가장 유연한 variant는 reader delegate와 결합된 GenericApplicationContext입니다.
예를 들어, 다음 예제에서 보듯이 XML 파일에 대해 XmlBeanDefinitionReader를
사용할 수 있습니다:
1GenericApplicationContext context = new GenericApplicationContext(); 2new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml"); 3context.refresh();
1val context = GenericApplicationContext() 2XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml") 3context.refresh()
다음 예제에서 보듯이 Groovy 파일에 대해서는 GroovyBeanDefinitionReader를
사용할 수도 있습니다:
1GenericApplicationContext context = new GenericApplicationContext(); 2new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy"); 3context.refresh();
1val context = GenericApplicationContext() 2GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy") 3context.refresh()
동일한 ApplicationContext에서 이러한 reader delegate를 혼합하여 사용할 수
있으며, 다양한 설정 소스에서 bean definition을 읽을 수 있습니다.
그런 다음 getBean을 사용하여 bean 인스턴스를 검색할 수 있습니다.
ApplicationContext 인터페이스에는 bean을 검색하기 위한 몇 가지 다른 메서드도
있지만, 이상적으로는 애플리케이션 코드가 이를 전혀 사용하지 않아야 합니다.
실제로 애플리케이션 코드는 getBean() 메서드를 전혀 호출하지 않아야 하며, 따라서
Spring API에 대한 dependency가 없어야 합니다. 예를 들어, web framework와의
Spring integration은 controller 및 JSF-managed bean과 같은 다양한 web framework
컴포넌트에 대해 dependency injection을 제공하여, autowiring 어노테이션과 같은
메타데이터를 통해 특정 bean에 대한 dependency를 선언할 수 있게 해줍니다.
Introduction to the Spring IoC Container and Beans
Bean Overview