개발/SPRING & JPA

[Spring-Core] 1.2 Container Overview

Leedo1982 2021. 4. 16. 20:08

org.springframework.context.ApplicationContext 인터페이스는 Spring IoC 컨테이너를 나타내며, 빈의 instantiating, confuguring, 조립을 담당한다. 컨테이너는 configuration metadata를 읽어 instantiate, configure, assemble 할 object에 대한 지침을 얻는다. configuration metadata는 XML, Java annotations, java code를 표시된다. 이를 통해 애플리케이션을 구성하는 object와 그 object 사이에 풍부한 상호 존속성을 표현할 수 있다.

 

몇몇 ApplicationContext 인터페이스의 구현은 Spring와 함께 제공된다. 독립 실행 애플리케이션에서는 , ClassPathXmlApplicationContext 또는 FileSystemXmlApplicationcontext의 인스턴스를 만드는 것이 일반적이다. XML 이 configuration metadata를 정의하는 전통적인 형식이었지만, 추가 metadat 형식에 대한 지원을 선언적으로 활성화하기 위해 적은 양의 XML 구성을 제고하여 컨테이너에 java annotations or code로 지시할 수 있다.

 

대부분 애플리케이션 시나리오에서, Spring IoC 컨테이너의 인스턴스를 하나 이상 인스턴스 화하는 데 명시적인 사용자 코드가 요구되진 않는다. 예를 들어, 웹 애플리케이션 시나리오에서, 응용 프로그램의 web.xml 파일에 있는 간단한 8 줄의 상용구 웹 설명자 XML이면 충분합니다. 만약 spring tools for eclipse를 사용하면, 더 쉽게 마우스 클릭이나, 키 입력으로 boilerplate configuration을 만들 수 있다.

 

다음 다이어 그램은 Spring의 작동방식에 대한 high-level을 보여준다. 애플리케이션 클래스는 configuration metadata와 결합되므로 ApplicationContext를 만들고 초기화한 후 완전히 구성되고 실행 가능한 시스템 또는 애플리케이션을 갖게 된다.

 

 1.2.1 Configuration Metadata

앞의 다이어 그램에서 볼 수 있듯이 , Spring IoC 컨테이너는 configuration metadata의 형식을 사용합니다. 이 configuration metadata는 애플리케이션 개발자로 spring 컨테이너에 애플리케이션 object를  인스턴스화, 구성 및 조립하도록 지시하는 방법을 나타냅니다. 

 

configuration metadata는 전통적으로 간단하고 직관적인 XML 형식으로 제공되며, 이 장의 대부분은 Spring IoC 컨테이너의 주요 개념과 기능을 전달하는 데 사용합니다.

 

더보기

XML 기반 메타데이터는 유일하게 허용되는 configuration metadata 형식이 아닙니다. spring IoC 컨테이너 자체는 이 configuration metadata 가 실제로 작성되는 형식과 완전히 분리되어 있습니다. 요즘 많은 개발자들이 Spring 애플리케[이션을 위해 JAVA 기반 구성(docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java)을 사용한다. 

 

Spring 컨테이너에서 다른 형식의 metadata를 사용하는 방법에 대한 정보는 다음과 같다.

- Annotation-based configuration(docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-annotation-config) : spring 2.5부터 지원되었다.

- Java-based configuration(docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java): Spring 3.0부터 Spring Javaconfig 프로젝트에서 제공하는 많은 기능이 행식 spring Framework에 일부가 되었다. 따라서 XML 파일이 아닌 Java를 사용하여 애플리케이션 외부에 Bean을 정의할 수 있습니다.

 

Spring 구성은 컨테이너가 관리해야 하는 하나이상의 Bean 정의로 구성됩니다.  XML 기반의 configuration metadata는 이런 beans을 "<bean/>"  요소로 감싼다, java 구성은 일반적으로 @Configuration 이 선언된 class에서   @Bean  annotation 메서드를 사용한다.

 

이러한 Bean 정의는 애플리케이션을 구성하는 실제 ojbect에 해당한다. 일반적으로 service layer objects, data access objects(DAO), Structs Action 인스턴스 등의  presentation object, Hibernate SessionFactories 같은 infrastructure object, jms 큐 등을 정의한다. 보통 도메인 객체를 만들고 로드하는 것은 DAO와 비즈니스 로직의 책임이기 때문에, 일반적으로 컨테이너에서 세분화된 도메인 object를 구성하지 않는다. 그러나  AspectJ와 Spring's integration을 사용하여 IoC 컨테이너 왜 부에서 생성된 Object를 구성할 수 있다. docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-atconfigurable를 참조하라.

 

다음 예는 XML 기반 configuration metadata를 보여준다.

<?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 속성 값을 협업 object를 나타냅니다. 협업 object를 참조하기 위한 XML 은 예제에 표시되지 않는다. 자세한 내용은 docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependencies를 참조하라.

1.2.2 Instantiating a Container

ApplicationContext 생성자에 제공되는 위치 경로는 컨테이너가 로컬 파일 시스템, Jaba CLASSPATH 등과 같은 다양한 외부 configuration metadata를 로드할 수 있도록 하는 문자열입니다.

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

다음 예는 service layer objects (service.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>

다음 예는 DAO Object의 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>

앞의 예에서 sevice layer는 PetStoreServiceImpl 클래스와 두 종류의 DAO object JpaAccountDao, JpaItemDao로 구성된다. property name  요소는 javaBean 요소의 이름을 참조하고, ref 요소는 또 다른 bean 정의서 이름을 참조한다. 이 id와 ref의 요소 사이의 연결은 공동 작업하는 object 간의 의존성을 나타낸다. 개체의 의존성을 고성 하는 상세는 세부사항을 참조하라(docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependencies)

 

Composing XML-based Configuration Metadata

bean 정의가 여러 XML 파일에 걸쳐 있도록 하는 것이 유용할 수 있습니다. 종종 각 개별 XML configuration 파일은 아키텍처의 논리 계층 또는 모듈을 나타냅니다.

 

애플리케이션 콘텍스트 생성자를 사용하여 이러한 모든 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 ) 모든 위치 경로는 가져오기를 수행하는 정의 파일과 상대적이므로 sevices.xml 은 가져오는 파일과 동일한 디렉터리 또는 클래스 경로 위치에 있어야 하며, messageSource.xml , themeSource.xml 은 가져오기 파일의 위치 아래에 있어야 한다. 보이는 것처럼 선행 슬래시(/)는 무시됩니다. 그러나 이러한 경로가 상대적이므로 슬래시를 전혀 사용하지 않는 것이 좋습니다. 최상의 <beans/> 요소를 포함하여 가져오는 파일의 내용은 Spring Schema에 따라 유요한 XML  Bean 정의 여야 한다. 

 

더보기

상대 '../' 경로를 사용하여 상위 디렉터리의 파일을 참조하는 것은 가능하지만 권장되지는 않습니다. 이렇게 하면 현재 응용프로그램 외부에 있는 파일에 대한 종속성이 생성됩니다. 

네임 스페이스 자체는 import 지시문 기능을 제공합니다. 일반 bean 정의를 넘어 추가 구성 기능은 Spring에서 제공하는 XML 네임 스페이스(ex: context 및 util 네임스페이스)에서 사용할 수 있습니다.

 

The Groovy Bean Definition DSL 

외부화된 구성 메타 데이터에 대한 추가 예로서, 빈 정의는 Grails 프레임 워크로 알려진 spring의 Groovy Bean Definitaion DSL에서도 표현될 수 있습니다. 일반적으로 이러한 구성은 다음 예에 표시된 '. groovy' 파일에 있습니다.

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
        }
    }
}

이 구성 스타일은 XML bean 정의와 거의 동일하며, Spring의 XML 구성 네임 스페이스도 지원합니다. 또한 ImportBeans 지시문을 통해 XML Bean 정의 파일을 가져올 수 있습니다.

 

1.2.3 Using the Container

ApplicationContext는 다른 bean과 그것들의 의존성의 등록을 유지하는 향상된 factory 능력을 위한 인터페이스입니다. T getBean(String name, Class <T> requeiredTyep) 메서드를 사용하여 bean을 조회할 수 있다.

 

ApplicationContext를 사용하면 다음 예제와 같이 Bean 정의를 읽고 access 할 수 있다.

// 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();

Groovy 구성을 사용하면 부트 스트랩이 매우 비슷해 보입니다. Groovy를 인식하는 다른 콘텍스트 구현 클래스가 있습니다.(하지만 XML 빈 정의도 이해한다.) 다음 예는 groovy 구성을 보여 줍니다.

ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");

가장 유연한 변형은 다음 예제와 같이 XML 파일의 경우 XmlBeanDefinitionReader와 함께 GenericApplicationContext를 조합하여 사용하는 것입니다.

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();

다음 예제와 같이 groovy 파일을 GroovyBeanDefinitionReader로 사용할 수 있습니다.

GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();

다양한 구성 소스에서 빈 정의를 일고, ApplicationContext와 같은 reader delegates를 혼합하고 일치시킬 수 있습니다.

 

그런 다음 getBean을 사용하여 빈 인스턴스를 조회할 수 있습니다. ApplicationContext 인터페이스는 이상적으로 응용프로그램 코드를 사용해서 안 되는 bean을 검색하기 위한 몇 가지 방법이 있다. 실제로 애플리케이션 코드는 getBean() 메서드에 대한 호출이 전혀 없어야 하면, SpringApi에 전혀 의존하지 않아야 한다.  예를들어 Spring의 웹 프레임 워크 통합은 JSP-managed beans과 같은 다양한 웹 프레임 워크 구성요소에 대한 종속성을 선언할 수 있습니다.