이 문서는 개인적인 목적이나 배포하기 위해서 복사할 수 있다. 출력물이든 디지털 문서든 각 복사본에 어떤 비용도 청구할 수 없고 모든 복사본에는 이 카피라이트 문구가 있어야 한다.
부록 C. XML 스키마에 기반을 둔 구성
C.1 소개
이번 부록에서는 스프링 2.0에서 도입되고 스프링 2.5와 3.0에서 강화되고 확장된 XML 스키마에 기반을 둔 구성을 살펴본다.
XML 스키마에 기반을 둔 구성파일로 바꾸는 주요 이유는 스프링 XML 구성을 더 쉽게 작성하는 것이다. '고전적인' <bean/>기반의 접근이 좋지만, 그 특성에 따라 구성에 오버헤드가 발생한다.
스프링 IoC 컨테이너의 관점에서는 모든 것이 빈이다. 모든 것이 빈이라면 같은 방식으로 이를 모두 다룰 수 있으므로 스프링 IoC 컨테이너의 입장에서는 좋은 점이지만 개발자 입장서는 그다지 좋지 않다. 스프링 XML 구성파일에서 정의한 객체는 모두 일반적이고 평범한(generic, vanilla) 빈이 아니다. 보통 각 빈은 어느 정도의 특별한 구성이 필요하다.
스프링 2.0에서 스키마에 기반을 둔 새로운 구성은 이 문제를 해결한다. <bean/> 요소는 계속 사용할 수 있고 원한다면 <bean/> 요소만 사용하면서 완전히 같은 방식의 스프링 XML 구성을 작성할 수 있다. 하지만 새로운 XML 스키마 기반의 구성은 스프링 XML 구성파일을 상당히 읽기 쉽게 만들 수 있고 빈 정의의 의도를 표현할 수 있다.
기존에 존재하는 빈(bean) 태그가 DAO, 서비스계층 객체, 밸리데이터 등의 애플리케이션에 특화된 빈에 적합하다면 새로운 커스텀 태그는 인프라스트럭처나 통합 빈(예를 들어 AOP, 컬렉션, 트랜잭션이나 Mule 등의 서드파티 프레임워크와의 통합)에 사용하기에 최적이라는 점은 꼭 기억해 두어야 한다.
다음의 예시로 스프링 2.0의 XML 스키마 지원이 추가된 것은 좋은 생각이었다는 점을 알 수 있기를 바란다. 개발자들이 이를 도입하기를 권장하고 이 새로운 구성 메커니즘이 완전히 커스터마이징할 수 있고 확장 가능하다는 점을 명심해라. 즉, 애플리케이션의 도메인을 더 잘 나타낼 수 있도록 자신의 도메인에 특화된 구성 태그를 작성할 수 있다. 자신만의 구성태그를 작성하는 방법은 부록 Appendix D, Extensible XML authoring에서 다룬다.
지금도 예전의 DTD 방식을 사용하는 스프링 구성 파일을 완전히 지원한다.
스프링 XML 구성파일을 작성할 때 새로운 XML 스키마 방식의 접근을 사용하더라도 문제는 전혀 없고 더 간결하고 깔끔한 구성을 사용할 기회를 놓칠 뿐이다. XML 구성이 DTD 기반이냐 스키마 기반이냐에 상관없이 결국은 컨테이너에서 같은 객체 모델이 된다.(보통 하나 이상의 BeanDefinition 인스턴스)
C.2 XML 스키마에 기반을 둔 구성
C.2.1 스키마 참조
기존의 DTD 방식에서 새로운 XML 스키마 방식으로 변경하려면 다음과 같이 바꾸어야 한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- <bean/> 정의는 여기에 작성한다 -->
</beans>
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 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- <bean/> 정의는 여기에 작성한다 -->
</beans>
'xsi:schemaLocation' 부분은 실제로는 필요 없지만 스키마의 로컬 복사본을 참조하려고(개발단계에서 유용할 수 있다.) 포함할 수 있다.
위의 스프링 XML 구성의 일부분은 복사 후 붙여넣기를 해서 사용할 수 있는 상용구문으로 항상 하듯이 <bean/>를 추가해서 사용할 수 있다. 하지만 XML 스키마 방식으로 바꾸는 것은 구성을 더 쉽게 만드는 새로운 스프링 2.0 XML 태그의 장점을 얻으려는 것이다. Section C.2.2, “util 스키마” 섹션에서 일반적인 유틸리티 태그를 사용해서 바로 시작하는 방법을 설명한다.
이번 장의 나머지 부분에서는 새로운 스프링 XML 스키마에 기반을 둔 구성의 예제를 보여준다. (새로운 태그마다 최소한 하나의 예시를 제공한다.) 형식은 before, after 형식을 사용해서 before 부분에서는 이전 방식의 XML을 보여주고(하지만 지금도 완전히 사용 가능한) 바로 이어서 나오는 after 부분에서는 같은 설정을 XML 스키마 방식을 보여준다.
C.2.2 util 스키마
처음 다룰 부분은 util 태그의 범위인데 이름에서 알 수 있듯이 util 태그는 컬렉션을 구성하거나 상수를 참조하는 등의 일반적인 유틸리티성 구성 이슈를 다룬다.
util 스키마의 태그를 사용하려면 스프링 XML 구성파일 상단에 다음 코드를 넣어야 한다. util 네임스페이스로 태그를 사용할 수 있도록 다음 예시의 텍스트는 올바른 스키마를 참조하고 있다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!-- 여기에 <bean/> 정의를 작성한다 -->
</beans>
C.2.2.1 <util:constant/>
Before...
<bean id="..." class="...">
<property name="isolation">
<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
</property>
</bean>
위 구성은 빈의 'isolation' 프로퍼티 값을 'java.sql.Connection.TRANSACTION_SERIALIZABLE' 상수 값으로 설정하려고 스프링의 FactoryBean 구현체인 FieldRetrievingFactoryBean를 사용한다. 이 구성은 문제없이 잘 동작하지만 약간 장황하고 (불필요하게) 스프링의 내부 구조를 최종 사용자에게 노출한다.
다음 XML 스키마 방식은 더 간단하면서도 개발자의 의도('이 상수값을 주입해라')를 명확하게 드러내서 더 읽기가 좋다.
<bean id="..." class="...">
<property name="isolation">
<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</property>
</bean>
필드 값으로 빈(bean) 프로퍼티나 생성자 인자 설정하기
FieldRetrievingFactoryBean은 static 필드 값이나 정적이 아닌 필드 값을 가져오는 FactoryBean이다. 이는 보통 public static final 상수를 가져오는 데 사용한다.(가져와서 또 다른 빈에 프로퍼티 값이나 생성자 인자를 설정하는 데 사용할 수 있다.)
staticField를 사용해서 static 필드를 노출하는 방법을 다음 예제에서 보여준다.
<bean id="myField" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>
빈 이름으로 static 필드를 지정하는 것도 편리한 사용방식이다.
<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>
이는 빈 id에 대한 선택권이 없다는 것을 의미하지만(그래서 이를 참조하는 다른 모든 빈도 이 긴 이름을 사용해야 한다) 이 형식은 매우 간단하게 정의할 수 있고 빈 참조에 id를 지정하지 않아도 되므로 이너 빈으로 사용할 때 아주 편리하다.
<bean id="..." class="...">
<property name="isolation">
<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
</property>
</bean>
FieldRetrievingFactoryBean 클래스의 API 문서에 나와 있듯이 다른 빈의 비정적(인스턴스) 필드에 접근하는 것도 가능하다. class.
스프링에서 빈에 프로프니나 생성사 인자로 enum 값을 주입하기는 아주 쉬워서 실제로 아무것도 안해도 되고 스프링 내부에 대해( FieldRetrievingFactoryBean같은 클래스) 알아야 하는 것도 없다. enum 값을 주입하기가 얼마나 쉬운지 예제를 통해서 보자. 다음과 같은 JDK 6 enum을 생각해 보자.
package javax.persistence;
public enum PersistenceContextType {
TRANSACTION,
EXTENDED
}
PersistenceContextType타입의 setter를 보자.
package example;
public class Client {
private PersistenceContextType persistenceContextType;
public void setPersistenceContextType(PersistenceContextType type) {
this.persistenceContextType = type;
}
}
이에 대한 빈 정의는 다음과 같다.
<bean class="example.Client">
<property name="persistenceContextType" value="TRANSACTION" />
</bean>
이는 (JDK 1.4와 JDK 1.3의) 전통적이면서 타입 세이프 하게 만들어진 enum에서도 잘 동작한다. 스프링은 enum 클래스의 상수와 일치하는 문자열 프로퍼티 값을 자동으로 찾을 것이다.
C.2.2.2 <util:property-path/>
Before...
<bean id="testBean" class="org.springframework.beans.TestBean" scope="prototype">
<property name="age" value="10"/>
<property name="spouse">
<bean class="org.springframework.beans.TestBean">
<property name="age" value="11"/>
</bean>
</property>
</bean>
<bean id="testBean.age" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
위 구성은 스프링의 FactoryBean 구현체 PropertyPathFactoryBean을 사용해서 'testBean' 빈의 'age' 프로퍼티와 같은 값을 가진 (int 타입의) 'testBean.age'라는 빈을 생성한다.
After...
<bean id="testBean" class="org.springframework.beans.TestBean" scope="prototype">
<property name="age" value="10"/>
<property name="spouse">
<bean class="org.springframework.beans.TestBean">
<property name="age" value="11"/>
</bean>
</property>
</bean>
<util:property-path id="name" path="testBean.age"/>
<property-path/> 태그의 'path' 속성의 값은 'beanName.beanProperty' 형식을 따른다.
빈 프로퍼티나 생성자 인자를 설정할 때 <util:property-path/> 사용하기
PropertyPathFactoryBean는 FactoryBean이고 주어진 대상 객체의 프로퍼티 경로를 평가한다. 대상 객체는 직접 지정할 수도 있고 빈 이름으로 지정할 수도 있다. 지정한 값은 다른 빈 정의에서 프로퍼티 값이나 생성자 인자로 사용할 수 있다.
다음은 name으로 다른 빈을 기준으로 path를 사용하는 예제이다.
// 대상 빈은 name으로 참조된다
<bean id="person" class="org.springframework.beans.TestBean" scope="prototype">
<property name="age" value="10"/>
<property name="spouse">
<bean class="org.springframework.beans.TestBean">
<property name="age" value="11"/>
</bean>
</property>
</bean>
// 이는 'person' 빈의 'spouse.age' 프로퍼티의 값인 11이 된다
<bean id="theAge"
class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="person"/>
<property name="propertyPath" value="spouse.age"/>
</bean>
이 예제에서 path는 내부 빈을 기준으로 평가된다.
<!-- 이는 내부 빈의 'age' 프로퍼티의 값인 12가 된다 -->
<bean id="theAge" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetObject">
<bean class="org.springframework.beans.TestBean">
<property name="age" value="12"/>
</bean>
</property>
<property name="propertyPath" value="age"/>
</bean>
빈 네임이 프로퍼티 경로인 단축형태도 존재한다.
<!-- 이는 'person' 빈의 'age' 프로퍼티의 값인 10이 된다 -->
<bean id="person.age"
class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
이 형식에서는 빈 이름을 선택할 수 없어서 이에 대한 모든 참조도 같은 id(경로)를 사용해야 한다. 물론 내부 빈으로 사용한다면 참조할 필요조차 없다.
<bean id="..." class="...">
<property name="age">
<bean id="person.age" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
</property>
</bean>
실제 정의에서 결과 타입을 구체적으로 지정할 수도 있다. 대부분 경우 이는 필요 없지만 일부의 경우에는 사용할 수 있다. 이 기능에 대한 자세한 내용은 Javadoc을 참조해라.
C.2.2.3 <util:properties/>
Before..
<!-- 제공한 위치에서 로드한 값으로 java.util.Properties 인스턴스를 생성한다 -->
<bean id="jdbcConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>
위 구성은 스프링의 FactoryBean 구현체인 PropertiesFactoryBean를 사용해서 제공된 Resource 위치에서 로드한 값으로 java.util.Properties 인스턴스를 인스턴스화 한다.
After...
<!-- 제공한 위치에서 로드한 값으로 java.util.Properties 인스턴스를 생성한다 -->
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>
C.2.2.4 <util:list/>
Before...
<!-- 제공한 'sourceList'에서 로드한 값으로 java.util.List 인스턴스를 생성한다 -->
<bean id="emails" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</list>
</property>
</bean>
위 구성은 스프링의 FactoryBean 구현체 ListFactoryBean을 사용해서 제공한 'sourceList'에서 가져온 값으로 초기화한 java.util.List 인스턴스를 생성한다.
After...
<!-- 제공한 값으로 java.util.List 인스턴스를 생성한다 -->
<util:list id="emails">
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</util:list>
명시적으로 정확히 List 타입을 제어할 수도 있는데 이는 <util:list/> 요소의 'list-class' 속성을 사용해서 인스턴스화한다. 예를 들어 java.util.LinkedList를 인스턴스화 하기를 원한다면 다음의 구성을 사용할 수 있다.
<util:list id="emails" list-class="java.util.LinkedList">
<value>jackshaftoe@vagabond.org</value>
<value>eliza@thinkingmanscrumpet.org</value>
<value>vanhoek@pirate.org</value>
<value>d'Arcachon@nemesis.org</value>
</util:list>
'list-class' 속성을 지정하지 않으면 컨테이너가 List 구현체를 선택할 것이다.
C.2.2.5 <util:map/>
Before...
<!-- 제공한 'sourceMap'에서 로드한 값으로 java.util.Map 인스턴스를 생성한다 -->
<bean id="emails" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="pechorin" value="pechorin@hero.org"/>
<entry key="raskolnikov" value="raskolnikov@slums.org"/>
<entry key="stavrogin" value="stavrogin@gov.org"/>
<entry key="porfiry" value="porfiry@gov.org"/>
</map>
</property>
</bean>
위 구성은 스프링의 FactoryBean 구현체 MapFactoryBean를 사용해서 제공한 'sourceMap'에서 가져온 키-값 쌍으로 초기화한 java.util.Map 인스턴스를 생성한다.
After...
<!-- 제공한 키-값 쌍으로 java.util.Map 인스턴스를 생성한다 -->
<util:map id="emails">
<entry key="pechorin" value="pechorin@hero.org"/>
<entry key="raskolnikov" value="raskolnikov@slums.org"/>
<entry key="stavrogin" value="stavrogin@gov.org"/>
<entry key="porfiry" value="porfiry@gov.org"/>
</util:map>
명시적으로 정확히 Map 타입을 제어할 수도 있는데 이는 <util:map/> 요소의 'map-class' 속성을 사용해서 인스턴스화 한다. 예를 들어 java.util.TreeMap를 인스턴스화 하기를 원한다면 다음 구성을 사용할 수 있다.
<util:map id="emails" map-class="java.util.TreeMap">
<entry key="pechorin" value="pechorin@hero.org"/>
<entry key="raskolnikov" value="raskolnikov@slums.org"/>
<entry key="stavrogin" value="stavrogin@gov.org"/>
<entry key="porfiry" value="porfiry@gov.org"/>
</util:map>
'map-class' 속성을 지정하지 않는다면 컨테이너가 Map 구현체를 선택할 것이다.
C.2.2.6 <util:set/>
Before...
<!-- 제공한 'sourceSet'에서 로드한 값으로 java.util.Set 인스턴스를 생성한다 -->
<bean id="emails" class="org.springframework.beans.factory.config.SetFactoryBean">
<property name="sourceSet">
<set>
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</set>
</property>
</bean>
위 구성은 스프링의 FactoryBean 구현체 SetFactoryBean를 사용해서 제공된 'sourceSet'에서 가져온 값으로 초기화한 java.util.Set 인스턴스를 생성한다.
After...
<!-- 제공한 값으로 java.util.Set 인스턴스를 생성한다 -->
<util:set id="emails">
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</util:set>
명시적으로 정확히 Set 타입을 제어할 수도 있는데 이는 <util:set/> 요소의 'set-class' 속성을 사용해서 인스턴스화한다. 예를 들어 java.util.TreeSet를 인스턴스화 하기 원한다면 다음 구성을 사용할 수 있다.
<util:set id="emails" set-class="java.util.TreeSet">
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</util:set>
'set-class' 속성을 지정하지 않으면 컨테이너가 Set 구현체를 선택할 것이다.
C.2.3 jee 스키마
jee 태그는 JNDI 객체를 찾고 EJB 참조를 정의하는 등의 Java EE (Java Enterprise Edition)와 관련된 구성 이슈를 다룬다.
jee 스키마의 태그를 사용하려면 스프링 XML 구성 파일 상단에 다음 부분을 추가해야 한다. 다음 예시의 내용은 올바른 스키마를 참조해서 jee 네임스페이스의 태그를 사용할 수 있다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- 여기에 <bean/> 정의를 작성한다 -->
</beans>
C.2.3.1 <jee:jndi-lookup/> (간단버전)
Before...
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDataSource"/>
</bean>
<bean id="userDao" class="com.foo.JdbcUserDao">
<property name="dataSource" ref="dataSource"/>
</bean>
After...
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>
<bean id="userDao" class="com.foo.JdbcUserDao">
<property name="dataSource" ref="dataSource"/>
</bean>
C.2.3.2 <jee:jndi-lookup/> (단일 JNDI 환경설정을 이용)
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDataSource"/>
<property name="jndiEnvironment">
<props>
<prop key="foo">bar</prop>
</props>
</property>
</bean>
After...
<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource">
<jee:environment>foo=bar</jee:environment>
</jee:jndi-lookup>
C.2.3.3 <jee:jndi-lookup/> (다중 JNDI 환경 설정을 이용)
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDataSource"/>
<property name="jndiEnvironment">
<props>
<prop key="foo">bar</prop>
<prop key="ping">pong</prop>
</props>
</property>
</bean>
After...
<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource">
<!-- 라인별로 구분되는 환경의 키-값 쌍 (표준 Properties 형식) -->
<jee:environment>
foo=bar
ping=pong
</jee:environment>
</jee:jndi-lookup>
C.2.3.4 <jee:jndi-lookup/> (복합 버전)
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDataSource"/>
<property name="cache" value="true"/>
<property name="resourceRef" value="true"/>
<property name="lookupOnStartup" value="false"/>
<property name="expectedType" value="com.myapp.DefaultFoo"/>
<property name="proxyInterface" value="com.myapp.Foo"/>
</bean>
After...
<jee:jndi-lookup id="simple"
jndi-name="jdbc/MyDataSource"
cache="true"
resource-ref="true"
lookup-on-startup="false"
expected-type="com.myapp.DefaultFoo"
proxy-interface="com.myapp.Foo"/>
C.2.3.5 <jee:local-slsb/> (간단 버전)
<jee:local-slsb/> 태그는 EJB Stateless SessionBean애 대한 참조를 구성한다.
Before...
<bean id="simple"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/RentalServiceBean"/>
<property name="businessInterface" value="com.foo.service.RentalService"/>
</bean>
After...
<jee:local-slsb id="simpleSlsb" jndi-name="ejb/RentalServiceBean"
business-interface="com.foo.service.RentalService"/>
C.2.3.6 <jee:local-slsb/> (복합 버전)b
<bean id="complexLocalEjb"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/RentalServiceBean"/>
<property name="businessInterface" value="com.foo.service.RentalService"/>
<property name="cacheHome" value="true"/>
<property name="lookupHomeOnStartup" value="true"/>
<property name="resourceRef" value="true"/>
</bean>
After...
<jee:local-slsb id="complexLocalEjb"
jndi-name="ejb/RentalServiceBean"
business-interface="com.foo.service.RentalService"
cache-home="true"
lookup-home-on-startup="true"
resource-ref="true">
C.2.3.7 <jee:remote-slsb/>
<jee:remote-slsb/> 태그는 remote EJB Stateless SessionBean에 대한 참조를 구성한다.
Before...
<bean id="complexRemoteEjb"
class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/MyRemoteBean"/>
<property name="businessInterface" value="com.foo.service.RentalService"/>
<property name="cacheHome" value="true"/>
<property name="lookupHomeOnStartup" value="true"/>
<property name="resourceRef" value="true"/>
<property name="homeInterface" value="com.foo.service.RentalService"/>
<property name="refreshHomeOnConnectFailure" value="true"/>
</bean>
After...
<jee:remote-slsb id="complexRemoteEjb"
jndi-name="ejb/MyRemoteBean"
business-interface="com.foo.service.RentalService"
cache-home="true"
lookup-home-on-startup="true"
resource-ref="true"
home-interface="com.foo.service.RentalService"
refresh-home-on-connect-failure="true">
C.2.4 lang 스키마
lang 태그는 스프링 컨테이너의 빈을 JRuby나 Groovy 같은 동적 언어로 작성한 경우 노출 객체를 다룬다.
이러한 태그(와 동적 언어 지원)은 Chapter 27, 동적 언어 지원 챕터에서 자세하게 다루었다. 동적 언어 지원과 lang 태그에 대한 자세한 내용은 이 챕터를 참고해라.
lang 스키마의 태그를 사용하려면 스프링 XML 구성파일의 상단에 다음 코드를 넣어야 한다. 다음 예시의 코드는 올바른 스키마를 참조해서 lang 네임스페이스의 태그를 사용할 수 있게 한다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
</beans>
C.2.5 jms 스키마
jms 태그는 스프링의 MessageListenerContainers처럼 JMS와 관련된 빈의 구성을 다룬다. 이러한 태그는 Section 22.6, “JMS 네임스페이스 지원”라는 제목의 JMS 챕터에서 자세히 설명했다. JMS 지원과 jms 태그에 대한 자세한 내용은 해당 챕터를 참고하기 바란다.
jms 스키마의 태그를 사용하려면 스프링 XML 구성파일 상단에 다음 코드를 넣어야 한다. 다음 예시의 코드는 올바른 스키마를 참조해서 jms 네임스페이스의 태그를 사용할 수 있게 한다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">
</beans>
C.2.6 tx (트랜잭션) 스키마
tx 태그는 스프링의 광범위한 트랜잭션 지원의 모든 빈의 구성을 다룬다. 이 태그는 Chapter 11, 트랜잭션 관리 장에서 다루었다.
스프링 배포판에 포함된 'spring-tx-3.0.xsd' 파일을 보기를 권장한다. (물론) 이 파일은 스프링 트랜잭션 구성의 XML 스키마로 기본 속성 등을 포함해서 tx 네임스페이스의 다양한 태그를 모두 다룬다. 이 파일은 문서에 포함되어 있으므로 DRY (Don't Repeat Yourself) 원리를 지키기 위해 여기서 다시 얘기하지는 않는다.
tx 스키마의 태그를 사용하려면 스프링 XML 구성파일 상단에 다른 코드를 넣어야 한다. tx 네임스페이스를 사용할 수 있도록 다음 예시의 텍스트는 올바른 스키마를 참조하고 있다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans>
tx 네임스페이스로 태그를 사용하는 경우 aop 네임스페이스의 태그도 사용할 수 있다. (스프링의 선언적인 트랜잭션 지원이 AOP로 구현되었으므로) 위 XML에 aop 스키마를 참조하기에 필요한 코드가 포함되어 있으므로 aop 네임스페이스의 태그를 사용할 수 있다.
C.2.7 aop 스키마
aop 태그는 스프링의 AOP와 관련된 모든 것을 다룬다. 이 태그는 스프링의 프락시 기반 AOP 프레임워크와 AspectJ AOP 프레임워크와의 스프링 통합을 포함한다. 이 태그는 Chapter 8, 스프링의 관점 지향 프로그래밍 장에서 자세히 다루었다.
aop 스키마의 태그를 사용하려면 스프링 XML 구성 파일 상단에 다음 코드를 넣어야 한다. 다음 코드에서 올바른 스키마를 참조하고 있으므로 aop 네임스페이스의 태그를 사용할 수 있다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans>
C.2.8 context 스키마
context 태그는 최종 사용자에게 중요한 빈이 아니라 일반적인 빈이 아니라 BeanfactoryPostProcessors 처럼 스프링에서 동작에 문제가 있는 빈과 관련된 plumbing과 관련된 ApplicationContext 구성을 다룬다. 다음 코드가 올바른 스키마를 참조하므로 context 네임스페이스의 태그를 사용할 수 있다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
</beans>
context 스키마는 스프링 2.5에서만 도입되었다.
C.2.8.1 <property-placeholder/>
이 요소는 ${...} 플레이스홀더를 지정한 프로퍼티 파일(Spring resource location처럼)로 처리해서 교체하게 한다. 이 요소는 PropertyPlaceholderConfigurer를 설정하는 편리한 방법이다. PropertyPlaceholderConfigurer를 더 세세하게 제어해야 한다면 명시적으로 직접 정의해라.
C.2.8.2 <annotation-config/>
(사용할 수 있는 경우) JSR 250의 @PostConstruct, @PreDestroy, @Resource와 (사용할 수 있는 경우) JPA의 @PersistenceContext, @PersistenceUnit와 마찬가지로 스프링의 @Required와 @Autowired같은 빈 클래스가 탐지한 다양한 어노테이션을 스프링 인프라가 활성화한다. 아니면 사용할 어노테이션에 대한 개별 BeanPostProcessors를 명시적으로 활성화할 수 있다.
이 요소는 스프링의 @Transactional 어노테이션을 활성화 하지 않는다. @Transactional 어노테이션을 활성화하려면
C.2.8.3 <component-scan/>
이 요소는 Section 4.9, “어노테이션기반의 컨테이너 설정”에 잘 나와 있다.
C.2.8.4 <load-time-weaver/>
이 요소는 Section 8.8.4, “스프링 프레임워크에서 AspectJ를 사용한 로드타임 위빙(Load-time weaving)”에 잘 나와 있다.
C.2.8.5 <spring-configured/>
이 요소는 Section 8.8.1, “스프링에 도메인 객체를 의존성 주입시 AspectJ 사용하기”에 잘 나와 있다.
C.2.8.6 <mbean-export/>
이 요소는 Section 23.4.3, “<context:mbean-export/> 요소”에 잘 나와 있다.
C.2.9 tool 스키마
tool 태그는 커스텀 설정 요소에 대한 도구에 국한된 메타데이터를 추가하고자 할 때 사용한다. 그 후 이 메타데이터를 이해할 수 있는 도구가 이 데이터를 사용해서 원하는 무엇이든 할 수 있다.(유효성 검사 등)
tool 태그는 현재 리뷰를 진행하고 있으므로 이번 스프링 릴리즈에는 문서로 만들어 져 있지 않다. 당신이 서드파티 벤더라서 이 리뷰 과정에 참여하고 싶다면 스프링 메일링 리스트에 메일을 보내라. 현재 지원하는 tool 태그는 스프링 소스 배포판의 'src/org/springframework/beans/factory/xml' 디렉토리에서 'spring-tool-3.0.xsd' 파일에 나와 있다.
C.2.10 beans 스키마
마지막으로 얘기하지만 무시할 수 없는 태그가 beans 스키마의 태그이다. 스프링 프레임워크의 아주 초창기부터 같은 태그가 존재하고 있다. beans 스키마의 태그는 Section 4.4.2, “의존성과 설정에 대한 자세한 내용”에서 아주 광범위하게 다루었으므로(전체 장에 걸쳐서 다루었다.) 여기서 beans 스키마의 다양한 태그의 예시를 보여주진 않는다.
스프링 2.0에서 beans 태그 자체에 새로 추가된 것 중 하나는 임의의 빈 메타데이터에 대한 아이디어이다. 스프링 2.0에서는 <bean/> XML 정의에 다수의 키/값 쌍을 추가하거나 추가하지 않을 수 있다. 이 여분의 메타데이터로 할 수 있는 일은 완전히 작성한 커스텀 로직에 달려 있다.(그리고 Appendix D, Extensible XML authoring 부록에서 설명한 대로 보통 커스텀 태그를 작성한 경우에만 사용한다.
상위의 <bean/> 컨텍스트에서 <meta/> 태그를 사용한 예제가 아래 나와 있다.(메타데이터를 해석하는 로직 없이는 아무런 효과가 없다는 점을 명심해라.)
<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-3.0.xsd">
<bean id="foo" class="x.y.Foo">
<meta key="cacheName" value="foo"/>
<property name="name" value="Rick"/>
</bean>
</beans>
위 예제에서 빈 정의를 사용하고 제공한 메타데이터로 캐시 인프라스트럭처를 구성할 어떤 로직이 있다고 가정할 수 있다.
Comments