Spring 공식 문서(영문)를 통해 공부한 내용이므로, 의역의 가능성이 있습니다.
1. IOC 컨테이너와 Bean
이번 챕터는 스프링 프레임워크 중 제어의 역전 (IoC - Inversion of Control)에 대해 다루어본다.
IoC는 Dependency Injection으로도 알려져 있다. DI는 개체가 자신의 역할 일부를 타 개체에 넘기고, 대신해준 역할의 결과값만을 받아오는 것을 의미한다.
org.springframework.beans
org.springframework.context
위 두 가지가 스프링 프레임워크 IoC 컨테이너의 기본 패키지이다.
BeanFactory인터페이스가 모든 종류의 개체에 대한 설정을 제공하며, ApplicationContext 는 Beanfactory의 서브 인터페이스이다.
ApplicationContext가 제공하는 기능으로는 :
- 스프링의 AOP 기능들을 쉽게 사용하도록 지원
- 이벤트 생성
- WebApplicationContext 와 같은 애플리케이션 수준의 컨텍스트 이용
2. Container 개요
org.springframework.context.ApplicationContext 인터페이스는 IoC 컨테이너를 대표하는 패키지이며, bean의 생성, 설정, 결합 등을 책임진다. 이 과정에서 필요한 정보를 configuration 메타 데이터에서 읽어오는데, 메타데이터는 XML, 어노테이션 혹은 자바 코드가 될 수도 있다.
XML에는 기초적인 메타데이터를 가지고 있고, 세부적인 설정을 위해 어노테이션이나 코드 등을 활용해야 한다.
XML은 추가적인 메타테이터를 설정하기 위한 기초만을 제공하는게 그 역할이다.
위 그림은 스프링이 동작하는 방식을 대략적으로 보여준다.
메타 데이터로부터 설정들이 정해지고, ApplicationContext가 생성된 후, 내가 입력한 값들을 이용하여 실행가능한 프로그램이 만들어진다.
3. Configuration Metadata 구성 메타데이터
구성 메타데이터는 예전부터 XML형태로 제공되는게 일반적이었지만, 최근 개발자들은 Java 기반의 Configuration을 선택하고 있다.
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="...">
<!-- 이 빈에 대한 설정 내용 -->
</bean>
<bean id="..." class="...">
<!-- 이 빈에 대한 설정 내용 -->
</bean>
<!-- 아래에 bean 추가 ... -->
</beans>
여기서 자바 기반의 구성이란 아래와 같은 어노테이션들을 일컽는다.
@Bean
@Configuration
@PropertySource
빈(Bean)으로 정의된 개체들은 Service, Dao, Action(Struts), SessionFactories, Queues(JMS) 등에 사용된다.
4. Container 생성하기
ApplicationContext 생성자에 외부 configuration 파일 경로를 String 형태로 넣어준다.
package com.kdh.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IocContainer {
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
}
여기서 services.xml, daos.xml 두 가지가 configuration 파일이다.
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>
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, 다오는 JpaAccountDao, JpaItemDao 가 있다.
services.xml 파일에서 property name이란 자바 빈 객체의 이름을 뜻하며, ref 속성은 해당 빈 정의의 다른 이름을 뜻한다. id와 ref 속성간의 관계가 바로 dependency를 의미한다.
5. XML기반의 속성 메타데이터 생성하기
여러개의 XML파일에 빈을 정의하는 것은 실용적인 방법이다. 이 경우엔 각각의 XML파일당 하나의 모듈에 대응한다.
Application Context constructor를 이용해 여러 XML파일들을 한 번에 불러올 수 있다. 아래와 같이 import 태그당 하나의 파일을 불러오며, 내부엔 복수의 resource 속성이 존재한다.
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
resource의 속성값은 각각 xml파일의 경로를 의미하는데, 이 경로는 상대 경로이므로 service.xml 파일은 위의 constructor 파일과 동일한 경로에 존재해야 한다.
또한 경로를 나타낼 때 맨 앞의 슬래쉬(/) 는 무시된다. 상대 경로임을 감안하여 슬래쉬를 사용하지 않는 것이 직관적이다.
위의 constructor 파일과 import되는 파일들은 모두 스프링 규칙에 따라 작성되어야 한다.
+ groovy 파일 형태로 메타데이터 가져오기.
groovy 파일로도 bean 정의들을 추가할 수 있다. 그레일즈 프레임워크(Grails framework)에서 이용하는 것으로 알려져 있는데, 확장자가 .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
}
}
}
1.2.2 // 1.2.3
6. Container 활용
ApplicationContext는 여러 빈(bean)들의 생성과 유지, 종속성을 관리한다.
T getBean(String name, Class<T> requiredType) 메소드를 이용하여 빈 객체를 가져올 수 있다.
ApplicationContext를 이용해 빈을 가져오는 과정을 앞서 작성했던 코드에 추가했다.
// 자바 빈을 가지고 있는 xml 불러오기
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// 빈 객체를 인스턴스로 읽어오기
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// 읽어온 인스턴스를 활용하기
List<String> userList = service.getUsernameList();
'SpringRealize' 카테고리의 다른 글
[자바로 스프링 구현하기] 1. IoC 컨테이너 (0) | 2021.05.29 |
---|
댓글