[Spring BlazaDS Integration 레퍼런스] 3장 스프링 빈을 플렉스 리모팅용으로 공개하기
참조: http://static.springsource.org/spring-flex/docs/1.5.x/reference/html/index.html#introduction
3.1. 도입
스프링이 관리하는 MessageBroker 는 플렉스 클라이언트가 스프링 빈을 리모팅 호출할 수 있는 형태로 손쉽게 공개할 수 있게 해준다. 이 방법은 스프링 프레임워크가 제공하는 다른 리모팅 기술과 매우 유사한 방법이다. 리모팅은 기존의 스프링 빈을 마치 외부 설정 용으로 만들어 준다. MessageBroker 는 플렉스 AMF 데이터 형식과 자바 사이의 직렬화 및 역직렬화를 투명하게 처리해준다.
3.2. 리모팅 서비스 설정
BlazeDS RemotingService 는 BlazeDS XML 설정에 있는 remoting-config.xml을 추가할 때동으로 설정된다. 스프링이 관리하는 리모팅 목적지 만을 사용할 때는 이 설정 파일 없이 스프링 설정 파일에 message-broker 태그를 추가하면 감각적인 기본값에 의해 RemotingService 가 설정된다. 그 결과 BlazeDS 설정에 remoting-config.xml에 다음과 같이 설정하는 것과 같은 것이다.
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service"
class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true"/>
</adapters>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
</service>
이것은 애플리케이션 수준의 default-channels 설정이 있다고 가정한다는 것을 알아두자. 애플리케이션 수준 기본 설정에 의존하지 않는다면 원하는 서비스 관련 채널을 설정하는 것을 추천한다(아래 예제 처럼). 만약 애플리케이션 수준 기본값이 없다면, AMFEndpoint 를 사용하는 MessageBroker 에서 사용할 수 첫번째 가용 채널을 RemotingService의 기본값으로 설정한다.
만약 RemotingService에 설정되는 기본값을 더 명시적으로 제어하고 싶다면 message-broker 태그의 remoting-service remoyou하위 엘리먼트를 사용해서 설정할 수 있다.
<flex:message-broker>
<flex:remoting-service default-adapter-id="my-default-remoting-adapter"
default-channels="my-amf, my-secure-amf" />
</flex:message-broker>
만약 레거시 BlazeDS 애플리케이션의 기존 remoting-config.xml이 있다면 RemotingDestinationExporter가 투명하게 모든 스프링이 관리하는 리모팅 목적지로 이전하게 해준다.
3.3. remoting-destination 태그 사용하기
remoting-destination 설정 태그는 기존에 스프링이 관리해주고 있는 서비스를 플렉스 클라이언트에서 직접 리모팅 할 수 있도록 해준다. 다음 스프링 빈 설정은 productService 빈을 설정하고 있다.
<bean id="productService" class="flex.samples.product.ProductServiceImpl" />
그리고 message-broker 태그를 설정하여 스프링이 관리하는 MessageBroker가 있다고 가정하겠다. 이때 다음의 최상위 remoting-destination 태그가 productService라는 서비스 목적지를 플렉스 클라이언트가 리모팅할 수 있게 공개해준다.
<!-- Expose the productService bean for BlazeDS remoting -->
<flex:remoting-destination ref="productService" />
기본으로 플렉스 클라이언트에 공개되는 리모트 서비스 목적지는 목적지의 서비스 id로 빈 이름을 사용하는데 이 값을 remoting-destination 태그의 destination-id 애트리뷰트로 재정의할 수 있다.
remoting-destination 태그를 사용하는 방법의 대안으로 bean 정의의 하위 엘리먼트를 사용하는 방법이 있다. 도메인 계층 빈 설정과 플렉스 리모팅 같은 기반 관련 설정을 분리할 필요가 없을 때 사용할 수 있다. (분리하는 것이 테스트를 더 편하게 할 수 있다는 것을 명심하자.) 다음과 같은 설정은 위와 동일한 결과를 가져다준다.
<bean id="productService" class="flex.samples.product.ProductServiceImpl" >
<flex:remoting-destination />
</bean>
플렉스 클라이언트가 호출할 수 있는 메서드를 remoting-destination 태그의 include-methods와 exclude-methods 애트리뷰트를 사용해서 보다 엄격하게 관리할 수 있다. 목적지를 공개할 BlazeDS 채널은 channels 애트리뷰트를 사용해서 제어할 수 있다. (최상위 엘리먼트로 사용하든 내부 엘리먼트로 사용하든 이 애트리뷰트를 사용할 수 있다.) 좀 더 커스터마이징한 예제는 다음과 같다.
<flex:remoting-destination ref="productService"
include-methods="read, update"
exclude-methods="create, delete"
channels="my-amf, my-secure-amf" />
remoting-destination 태그는 공개하는 빈 마다 투명하게 RemotingDestinationExporter 빈 인스턴스를 등록해 준다. 네임스페이스를 사용하지 않고 빈 설정을 하면 다음과 같다.
<!-- Expose the productService bean for BlazeDS remoting -->
<bean id="product" class="org.springframework.flex.remoting.RemotingDestinationExporter">
<property name="messageBroker" ref="_messageBroker"/>
<property name="service" ref="productService"/>
<property name="destinationId" value="productService"/>
<property name="includeMethods" value="read, update"/>
<property name="excludeMethods" value="create, delete"/>
<property name="channels" value="my-amf, my-secure-amf"/>
</bean>
3.4. @RemotingDestination 사용해서 리모팅 빈 공개하기
@RemotingDestination 애노테이션은 XML 리모팅-목적지 태그 대안으로 사용할 수 있다. @RemotingDestination 은 클래스의 타입에 사용하여 해당 빈을 공개할 수 있다. @RemotingInclude와 @RemotingExclude를 메서드에 사용하여 해당 메서드를 리모팅에 포함할지 제외할지 설정할 수 있다.
다음 예제는 productService 빈을 애노테이션으로 리모팅 설정한 예에 해당한다.
package flex.samples.product;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.flex.remoting.RemotingExclude;
import org.springframework.flex.remoting.RemotingInclude;
import org.springframework.stereotype.Service;
@Service("productService")
@RemotingDestination(channels={"my-amf","my-secure-amf"})
public class ProductServiceImpl implements ProductService {
@RemotingInclude
public Product read(String id) {
...
}
@RemotingExclude
public Product create(Product product){
...
}
@RemotingInclude
public Product update(Product product){
...
}
@RemotingExclude
public void delete(Product product) {
...
}
}