[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) {

}

}

    


[Spring BlazaDS Integration 레퍼런스] 2장 스프링에서 BlazeDS MessageBroker 설정 및 사용

참조: http://static.springsource.org/spring-flex/docs/1.5.x/reference/html/index.html#introduction


2.1. 도입

스프링 BlazeDS Integration을 사용할 때 반드시 설정해야 하는 핵심 요소는 MessageBroker다. 플렉스 클라이언트에서 발생한 HTTP 메세지는 스프링 DispatcherServlet 을 통해 스프링이 관리하는 MessageBroker로 전달된다. 스프링이 관리하는  MessageBroker를 사용할 때는 BlazeDS MessageBrokerServlet 을 설정할 필요 없다.

2.2. 스프링 DispatcherServlet 설정

스프링 WebApplicationContext의 시작점(bootstrap)으로 보통 web.xml에 DispatcherServlet 을 다음과 같이 설정한다.

<!– The front controller of this Spring Web application, responsible for handling all application requests –>

<servlet>

    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/config/web-application-config.xml</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

</servlet>

2.3. 스프링에 MessageBroker 설정하기

WebApplicationContext에 MessageBroker를 설정할 때 편리한 스프링 XML 설정 네임스페이스가 제공된다. 그 네임스페이스를 사용하려면 스프링 XML 설정 파일에 스키마 위치를 추가해야 한다. 보통 다음 설정과 같을 것이다.

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans xmlns=”http://www.springframework.org/schema/beans”

  xmlns:flex=”http://www.springframework.org/schema/flex”

       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-2.5.xsd

           http://www.springframework.org/schema/flex 

           http://www.springframework.org/schema/flex/spring-flex-1.0.xsd”>

</beans>

    

    

이렇게 하면 설정 파일에서 flex 네임스페이스로 스프링 BlazeDS Integration 설정 태그를 사용할 수 있다. 다음 예제부터는 위와같이 설정했다고 가정을 하겠다. 이 네임스페이스에서 사용할 수 있는 모든 태그과 애트리뷰트는 spring-flex-1.0.xsd를 참조하기 바란다. 이클립스 같은 XSD를 인식하는 XML 편집기에서는 우리가 타이핑하는 것에 따라 문서를 자동으로 읽어줄 것이다.

스프링 WebApplicationContext에 최소한 MessageBrokerFactoryBean 을 설정하여 MessageBroker를 가동시켜야 하며 MessageBrokerHandlerAdapter 와 적절한  HandlerMapping (보통 SimpleUrlHandlerMapping) 을 사용하여 요청을 스프링이 관리하는  MessageBroker에 전달되게 해야한다. 

빈 설정 파일에 message-broker 태그를 등록하면 그러한 빈들을 자동으로 등록해 준다. 다음 예제가 가장 간단한 형태다.

<flex:message-broker/>    

    

이렇게 하면 MessageBroker 를 설정하고 필요한 기반 요소를 감각적인 기본값(sensible defaults)으로 설정해 준다. 그렇게 사용하는 기본값들은 message-broker 태그의 애트리뷰트 또는 하위 엘리먼트를 사용해서 재정의 할 수 있다. 예를 들어 BlazeDS XML 설정 파일의 기본 위치(/WEB-INF/flex/services-config.xml)를 services-config-path 애트리뷰트로 재정의할 수 있다. MessageBrokerFactoryBean 은 스프링의 ResourceLoader 추상화를 사용하기 때문에 스프링 리소스 패스를 사용할 수 있다. 그 예로, 애플리케이션 클래스패스에서 설정을 읽어오도록 다음과 같이 설정할 수 있다.

<flex:message-broker services-config-path=”classpath*:services-config.xml”    

    

이와 동일한 순수 스프링 설정을 사용한 MessageBrokerFactoryBean 정의는 다음과 같다. 

<!– Bootstraps and exposes the BlazeDS MessageBroker –>

<bean id=”_messageBroker” class=”org.springframework.flex.core.MessageBrokerFactoryBean” >

<property name=”servicesConfigPath” value=”classpath*:services-config.xml” />

</bean>    

    

message-broker 태그에서 특히 주목할 점은 MessageBroker에 커스텀 id를 설정할 필요가 없다는 것이다. 나중에 참조할 일도 없기 때문에 사실 그렇게 하는 것을 권장하지 않는다. 커스텀 id를 설정해야 하는 상황은 오직 WebApplicationContext에 MessageBroker를 두개 이상 가동할 경우이다.


2.4. 요청을 MessageBroker쪽으로 매핑하기

들어오는 요청을 스프링이 관리하는 MessageBroker로 전달하려면 세곳에 요청 매핑을 설정해야한다. 

  • web.xml에 DispatcherServlet 매핑
  • 스프링 WebApplicationContext에 HandlerMapping
  • BlazeDS services-config.xml에 채널 정의

가장 간단한 요청 매핑 시나리오는 앞단에 위치한 플렉스가 애플리케이션의 유일한 클라이언트인 경우이다. 이런 경우 /messagebroker를 요청 최상위 패스로 매핑할 수 있다. 그런 경우 web.xml에 다음과 매핑할 것이다.

<!– Map all /messagbroker requests to the DispatcherServlet for handling –>

<servlet-mapping>

    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>

    <url-pattern>/messagebroker/*</url-pattern>

</servlet-mapping>    

message-broker 설정 태그를 사용하면  SimpleUrlHandlerMapping 이 설정되어 DispatcherServlet 으로 전달되는 모든 요청을 /* 경로 패턴을 따라 스프링이 관리하는 MessageBroker 에 매핑한다. 자신이 직접 작성한 HandlerMapping 빈을 설정할 때는   message-broker 태그의 disable-default-mapping 애트리뷰트를 사용해서 기본 매핑 사용을 제어할 수 있다. 기본으로 설정되는 SimpleUrlHandlerMapping 의 순서는 mapping-order 애트리뷰트로 설정할 수 있다. (동일한 컨텍스트에 여러 핸들러 매핑 타입이 존재하는 복잡한 경우에 사용할 수 있겠다.)

스프링 WebApplicationContext의 SimpleUrlHandlerMapping 은 모든 요청을 MessageBrokerHandlerAdapter를 통해 스프링이 관리하는 MessageBroker로 전달한다. 기본으로 설정되는 message-broker 태그는 다음과 같은 빈 정의와 동일하다.

<!-- Maps request paths at /* to the BlazeDS MessageBroker -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /*=_messageBroker
        </value>
    </property>
</bean>

<!-- Dispatches requests mapped to a MessageBroker -->
<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter"/>    
		

BlazeDS services-config.xml의 채널 정의가 반드시 선택한 매핑에 대응해야 한다. 예를 들어, 위 매핑 전략에 대응하는 AMF 채널을 BlazeDS에 다음과 같이 설정할 수 있다. 

 

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
    <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" 
    	class="flex.messaging.endpoints.AMFEndpoint"/>
    <properties>
        <polling-enabled>false</polling-enabled>
    </properties>
</channel-definition> 		
		

services-config.xml에 커뮤니테이션 채널을 설정하는 더 자세한 방법은  BlazeDS documentation 에서 참조하기 바란다.


2.5. 스프링 MVC 컨트롤러와 플렉스 클라이언트 같이 사용하기

플렉스 기반 클라이언트 뿐 아니라 더 다양한 클라이언트를 지원하는 애플리케이션이 더 흔할 것이다. 예를 들어 RESTful 아키텍처를 구성하여 여러 종류의 클라이언트를 지원할 수 있다. 잠재적으로 플렉스 HTTPService 컴포넌트를 사용하여 RESTful 종점(endpoint)를 구독할 수도 있다. 스프링 MVC의 컨트롤러 모델은 RESTful 종점 같은 것을 만들기 단순하며, 유연한 방법들을 제공한다. 이러한 하이브리드 웹 애플리케이션 시나리오에서는 다른 방식의 매핑 전략이 필요하다.

가장 간단한 방법은 여러 DispatcherServlet과 계층형 애플리케이션 컨텍스트를 사용하는 것이다. 이 방법에서는 주요 애플리케이션 계층(서비스, 보안, 기반시설 지원, 등)을 ContextLoaderListener가 로딩하는 상위 컨텍스트에 두고, 스프링 MVC 컨트롤러들을 그 하위 DispatcherServlet 컨텍스트에 두고, 플렉스 클라이언트와 관련된 모든 것들을 별도의 DispatcherServlet 컨텍스트에 두는 것이다. 이 방법을 적용한 web.xml은 다음과 같다.

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>

        /WEB-INF/spring/*-context.xml

    </param-value>

</context-param>

<listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<servlet>

    <servlet-name>flex</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

    <servlet-name>flex</servlet-name>

    <url-pattern>/messagebroker/*</url-pattern>

</servlet-mapping>

<servlet>

    <servlet-name>spring-mvc</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

    <servlet-name>spring-mvc</servlet-name>

    <url-pattern>/spring/*</url-pattern>

</servlet-mapping> 

 /WEB-INF/spring/ 디렉토리에  -context.xml 로 끝나는 파일 그룹을 묶어서 부모 애플리케이션 컨텍스트를 만든다. 플렉스 관련 하위 컨텍스트는  /WEB-INF/flex-servlet.xml을 사용하고 스프링 MVC 컨트롤러는 WEB-INF/spring-mvc-servlet.xml안에 설정할 것이다. 이 방법은 깔끔하게 관심사를 분리해주며 스프링 2.5+ 애노테이션 컨트롤러가 기본으로 동작하게 해준다.

이 대안이 될 수 있는 방법으로는 단일 DispatcherServlet 컨텍스트를 사용하는 것이다. 이 방법의 단점은 몇 가지 부가적인 설정을 필요로 한다. /spring/* 요처을 DispatcherSerlvet이 처리하고 mapping XML 네임스페이스 설정 태그를 사용해서 /messagebroker/*를 스프링이 관리하는 MessageBroker로 전달하는 것이다. 그런다음 BlazeDS 채널 정의를 적절하게 수정해야 한다. message-broker 태그로 기본 매핑 전략을 다음과 같이 수정할 수 있다.

<flex:message-broker>

    <flex:mapping pattern=”/messagebroker/*” />

</flex:message-broker> 

그런다음 BlazeDS의 채널 정의에서 /spring/*을 고려해서 다음과 같이 수정해야 한다. 

<channel-definition id=”my-amf” class=”mx.messaging.channels.AMFChannel”>

    <endpoint url=”http://{server.name}:{server.port}/{context.root}/spring/messagebroker/amf” 

    class=”flex.messaging.endpoints.AMFEndpoint”/>

    <properties>

        <polling-enabled>false</polling-enabled>

    </properties>

</channel-definition> 

단일 매핑 전략에서는 message-broker 태그가 자동으로 등록해주는 HandlerMapping과 HandlerAdapter가 있기 때문에 스프링 MVC 문서에 따라 스프링 MVC 컨트롤러를 위한 HandlerMapping와 HandlerAdapter을 직접 등록해 줘야 한다.

[Adobe] BlazeDS는 뭔가?

http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/

스프링 BlazeDS라는 프로젝트가 있다. 근데 BlazeDS가 뭔지 모른다. 그래서 살펴봤다.
어도비 플랙스나 에어로 클라이어언트 단을 만들고 자바로 만든 서버 단과 연동하는데 필요한 서비스를 제공해준다. 거기다.. XML이나 SOAP 같은 텍스트 기반 서비스 보다 10배나 빠르단다.. 흠…. Push 기능도 구현할 수 있게 해준다는데.. 조금. 구미가 땡기기 시작한다.
주요 서비스는 다음과 같다.
– 리모팅: 서버단의 자바로 만든 서비스를 바로 호출할 수 있게 해준다.
– 메세지 서비스: 배포/구독 방식 메시징으로 실시간으로 데이터를 주고 받는 애플리케이션을 개발할 수 있다.
– 프록시 서비스: 뭔지 감이 잘 안옴.

[Adobe Flex] 초간단 Todo Flex 만들기 2: 스프링 액션스크립트 설정하기.

libs 폴더에 보이는 라이브러리 4개를 클래스패스에 추가합니다.
그런다음 빈 설정파일인 application-context.xml 파일을 작성합니다.

<?xml version=”1.0″ encoding=”utf-8″?>

<objects xmlns=”http://www.springactionscript.org/schema/objects”

         xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

         xsi:schemaLocation=”http://www.springactionscript.org/schema/objects

http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.xsd”>

<!–

Spring ActionScript config

–>

<object id=”autowiringStageProcessor” class=”org.springextensions.actionscript.stage.DefaultAutowiringStageProcessor”/>

<object id=”eventHandlerProcessor” class=”org.springextensions.actionscript.ioc.factory.config.EventHandlerMetaDataPostProcessor”/>

<!–

Infrastructure: services

–>

<object id=”todoService” class=”whiteship.crud.infrastructure.service.InMemoryTodoService”/>

<!–

Presentation: presentation models

–>

<object class=”whiteship.crud.presentation.TodoListPresentationModel”>

<constructor-arg ref=”todoService”/>

</object>

</objects>

http://www.springactionscript.org/asdoc/org/springextensions/actionscript/stage/DefaultAutowiringStageProcessor.html

살펴볼만한 API는 위 링크를 보시면 될 것 같군요. 나머지 설정 내용은 어떤것인지 대충 짐작이 갈 것 같습니다. bean대신 object를 사용하네요. 흠.. 머 더 알고 싶은게 없어서 이만;;

이 설정파일을 사용해서 ApplicationContext를 만드는 코드는 simpleCRUD.mxml 파일에 들어있습니다.

private var _appContext:FlexXMLApplicationContext = new FlexXMLApplicationContext();

_appContext.addConfigLocation(“application-context.xml”);

_appContext.load();

다음에는 오토와이어링 사용법좀 봐야겠네요. 오늘은 이만~

[Adobe Flex] 초간단 Todo Flex 만들기 1: 돌아가는 예제

스프링 액션스크립트 예제 애플리케이션을 살짝 개조해서 Todo 애플리케이션을 만들었습니다. 초간단 버전이라 DB도 사용하지 않고 그냥;; 추가/수정/삭제/리스트 정도만 되는 애플리케이션을 만들어 봤습니다. 액션스크립트도 잘 모르고 플렉스도 잘 모르지만 예제 코드 고쳐가며서 만드니까 대충 만들 수 있겠더군요;
맥용 플래시 빌더로 만들었는뎅;; 인텔리J에서도 배포하는 방법을 터득해야 할텐데;; 일단 Todo로 미루고;;
소스코드를 올려둡니다.