Spring + BlazeDS RC1集成指南

来源:互联网 发布:百年战争 知乎 编辑:程序博客网 时间:2024/05/17 23:01
Spring + BlazeDS RC1集成指南 
参考:《spring_flex_refenence.pdf》 
Spring BlazeDS Integration 
Version 1.0.0.RC1 Spring BlazeDS Integration ii 
作者: Jeremy Grelle 
版本: 1.0.0.RC1 

内容: 
1. 项目背景和运行环境 
2. 用spring来配置 和使用 BlazeDS MessageBroke 
3. 为flex RPC声明 bean 
4. 结合spring的安全机制来设置 BlazeDS的Destinations 
5. 集成BlazeDS 消息服务 

【1. Spring BlazeDS Integration Overview】 
【1.1. Background】 --背景接收,大家都知道spring的厉害,就不说了。 
Spring has always aimed to be agnostic to the client technologies being used to access its core services, 
intentionally leaving options open and letting the community drive the demand for any new first-class 
integration solutions to be added to the Spring project portfolio. Spring BlazeDS Integration is an answer 
to the commmunity demand for a top-level solution for building Spring-powered Rich Internet 
Applications using Adobe Flex for the client-side technology. 
BlazeDS is an open source project from Adobe that provides the remoting and messaging foundation for 
connecting a Flex-based front-end to Java back-end services. Though it has previously been possible to 
use BlazeDS to connect to Spring-managed services, it has not been in a way that feels "natural" to a 
Spring developer, requiring the extra burden of having to maintain a separate BlazeDS xml configuration. 
Spring BlazeDS Integration turns the tables by making the BlazeDS MessageBroker a Spring-managed 
object, opening up the pathways to a more extensive integration that follows "the Spring way". 
【1.2. 运行软件需求】 
Java 5 or higher 
Spring 2.5 or higher 
Adobe BlazeDS 3.2 or higher 
【1.3. Where to get support】 
Professional from-the-source support on Spring BlazeDS Integration is available from SpringSource, the 
company behind Spring. 

【2. 配置 spring + blazeDS 开始】 
【2.1. 介绍】 
主要的BlazeDS组件是MessageBroker. Flex端传入的http信息将会通过Spring的DispatcherServlet来触发Spring-managed MessageBroker. 
也就是说spring用DispatcherServlet来管理BlazeDS的MessageBroker,用过BlazeDS的都知道,在web.xml里面有: 
Java代码  收藏代码
  1. <servlet>  
  2.     <servlet-name>MessageBrokerServlet</servlet-name>  
  3.     <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>  
  4.     <init-param>  
  5.         <param-name>services.configuration.file</param-name>  
  6.         <param-value>/WEB-INF/flex/services-config.xml</param-value>  
  7.    </init-param>  
  8.     <load-on-startup>3</load-on-startup>  
  9. </servlet>  

    现在spring,把这个BlazeDS的MessageBrokerServlet代理了,用org.springframework.web.servlet.DispatcherServlet. 
【2.2. 配置spring的 DispatcherServlet】 
在web.xml里面,相应的位置加入: 
Java代码  收藏代码
  1. <!-- The front controller of this Spring Web application, responsible for handling all application requests -->  
  2. <servlet>  
  3.     <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>  
  4.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  5.     <init-param>  
  6.     <param-name>contextConfigLocation</param-name>  
  7.     <param-value>/WEB-INF/config/web-application-config.xml</param-value>  
  8.     </init-param>  
  9.     <load-on-startup>1</load-on-startup>  
  10. </servlet>  

【2.3. 在spring的bean工厂里面配置 MessageBroker】 
在spring 的XML配置文件头部加入MessageBroker的命名空间namespace。如下: 
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3. xmlns:flex="http://www.springframework.org/schema/flex"  
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5. xsi:schemaLocation="  
  6. http://www.springframework.org/schema/beans  
  7. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  8. http://www.springframework.org/schema/flex  
  9. http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">  
  10. ...  
  11. </beans>  

详细的标签信息在 spring-flex-1.0.xsd里面。 
首要的就是要配置 MessageBrokerFactoryBean 在application-config.xml文件里面,在系统启动的时候通过这个 MessageBrokerFactoryBean来启动 BlazeDS的MessageBroker, 
这样通过 MessageBrokerHandlerAdapter 和 HandlerMapping(通常是SimpleUrlHandlerMapping)来把flex端的消息路由到spring里面。 

在application-config.xml里面,用<flex:message-broker/>标签来配置 MessageBrokerFactoryBean,并且需要指定BlazeDS的 services-config.xml作为参数,举例如下: 
通常BlazeDS 配置的XML文件在(/WEB-INF/flex/services-config.xml)。 
Java代码  收藏代码
  1. <bean id="_messageBroker" class="org.springframework.flex.messaging.MessageBrokerFactoryBean" >  
  2. <property name="servicesConfigPath" value="classpath*:services-config.xml" />  
  3. </bean>  


【注意】 
Note especially that with the message-broker tag, it is not necessary to assign a custom id to the 
MessageBroker, and it is in fact discouraged so that you won't have to continually reference it later. The 
only reason you would ever need to provide a custom id is if you were bootstrapping more than one 
MessageBroker in the same WebApplicationContext. 

【2.4. 把Flex端通过BlazeDS的请求转到 spring 来接管】 
为了把请求路由到 spring-managed MessageBroker,需要做3个地方的配置: 
1. 在web.xml里面配置 DispatcherServlet 
2. 在spring bean工厂里面配置 HandlerMapping 
3. 在BlazeDS services-config.xml里面配置 Channel 的 definitions 

===>在web.xml里面: 
Java代码  收藏代码
  1. <!-- Map all /messagbroker requests to the DispatcherServlet for handling -->  
  2. <servlet-mapping>  
  3. <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>  
  4. <url-pattern>/messagebroker/*</url-pattern>  
  5. </servlet-mapping>  


===> 
用了spring来接管BlazeDS的 messagebroker后,就会产生一个缺省的SimpleUrlHandlerMapping来接收所有通过DispatcherServlet传来的 message请求。 
这个缺省的SimpleUrlHandlerMapping将会被覆盖,当有您的系统配置了多个类似这样的mapping累。当你需要自定义HandlerMapping时, 
您必须在配置 message-broker时,通过 disable-default-mapping 属性来屏蔽掉那个缺省的 SimpleUrlHandlerMapping。 
当您的应用中配置了多个 handlermapping时,mapping-order属性可以指定handlermapping的顺序。 
以下的配置是 SimpleUrlHandlerMapping接收所有的flex端的message请求: 
Java代码  收藏代码
  1. <!-- Maps request paths at /* to the BlazeDS MessageBroker -->  
  2. <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
  3. <property name="mappings">  
  4. <value>  
  5. /*=_messageBroker  
  6. </value>  
  7. </property>  
  8. </bean>  
  9. <!-- Dispatches requests mapped to a MessageBroker -->  
  10. <bean class="org.springframework.flex.messaging.servlet.MessageBrokerHandlerAdapter"/>  

===> 
Channel definitions设置: 使用BlazeDS,该文件路径在 services-config.xml, 
下面的配置正好符合上面那个haddlermapping的策略; 
Java代码  收藏代码
  1. <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">  
  2. <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"  
  3. class="flex.messaging.endpoints.AMFEndpoint"/>  
  4. <properties>  
  5. <polling-enabled>false</polling-enabled>  
  6. </properties>  
  7. </channel-definition>  


应用系统可以为flex端配置不通的 hadlermapping策略,比如有的handlermapping用来处理 rpc请求,有的用来处理HTTPService请求, 
那么这个时候,就要类似在web.xml里面配置servlet mapping一样,为不同的 handlermapping指定不同的pattern,来识别不同的请求。 
比如: 
pattern=/spring/*  指向 DispatcherServlet 
pattern=/messagebroker/*  指向 Spring-managed MessageBroker 
应用必须按照如下来修改mapping策略: 
Java代码  收藏代码
  1. <flex:message-broker>  
  2. <flex:mapping pattern="/messagebroker/*" />  
  3. </flex:message-broker>  

然后配置 一个channel definitions如下: 
Java代码  收藏代码
  1. <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">  
  2. <endpoint url="http://{server.name}:{server.port}/{context.root}/spring/messagebroker/amf"  
  3. class="flex.messaging.endpoints.AMFEndpoint"/>  
  4. <properties>  
  5. <polling-enabled>false</polling-enabled>  
  6. </properties>  
  7. </channel-definition>  

【2.5. flex端使用 Spring-managed Destinations】 
Client 
Explicit channel definition is a requirement when using dynamic destinations (meaning any destination 
that is added programmatically and not defined in the BlazeDS services-config.xml, i.e. the destinations 
created by the remoting-destination tag and the various *-message-destination tags). 
See Adobe's documentation here for more detail: 
http://livedocs.adobe.com/blazeds/1/blazeds_devguide/runtimeconfig_5.html#194376 
The only way you don't have to explicitly define the ChannelSet on the client is if 

1. you are using explicitly defined destinations in services-config.xml (i.e, not dynamic destinations) 
AND you compile your flex client against that file 
2. your destination is using the application-wide default channel AND you compile your flex client 
against that file 
Even if you weren't using dynamically created destinations it is debatable whether it is a good idea to ever 
compile your client against services-config.xml, thus coupling your client to your server configuration. It 
is often desirable to keep your flex client and your server side code as two distinct modules, but 
compiling against services-config.xml blurs the lines between those modules. 

Our recommendation is that it is generally cleaner to keep the client-side configuration of ChannelSets 
explicitly contained within the client module. An excellent way to do this without having to hard-code the 
URLs in your client code is to use an ActionScript DI framework such as Spring ActionScript (a Spring 
Extensions project, formerly known as Prana). 
If you choose to go the route of compiling your client against services-config.xml, note that you can at 
least keep the URL information out of the client code by using ServerConfig.getChannel as described in 
the referenced BlazeDS documentation. 

【2.6. 高级的MessageBroker配置】 
The initialization of the MessageBroker by the MessageBrokerFactoryBean logically consists 
of two phases: 
1. Parsing the BlazeDS XML configuration files and applying their settings to a newly created 
MessageBroker 
2. Starting the MessageBroker and its services 
A special MessageBrokerConfigProcessor callback interface is provided that allows custom 
processing to be done on the newly created MessageBroker after each phase, before it is made available 
for request processing. This interface is used internally by Spring BlazeDS Integration, but is also 
available for general use in advanced programmatic introspection and customization of the 
MessageBroker. A custom MessageBrokerConfigProcessor can be configured as a Spring 
bean and then registered with the MessageBrokerFactoryBean via the config-processor tag. 
For example, given a trivial implementation to log some additional info about the MessageBroker: 
Java代码  收藏代码
  1. package com.example;  
  2.   
  3. import org.springframework.flex.messaging.config.MessageBrokerConfigProcessor;  
  4. import flex.messaging.MessageBroker;  
  5. import flex.messaging.services.RemotingService;  
  6.   
  7. public class MyDestinationCountingConfigProcessor implements  
  8.         MessageBrokerConfigProcessor {  
  9.     public MessageBroker processAfterStartup(MessageBroker broker) {  
  10.         RemotingService remotingService = (RemotingService) broker  
  11.                 .getServiceByType(RemotingService.class.getName());  
  12.         if (remotingService.isStarted()) {  
  13.             System.out.println("The Remoting Service has been started with "  
  14.                     + remotingService.getDestinations().size()  
  15.                     + " Destinations.");  
  16.         }  
  17.         return broker;  
  18.     }  
  19.   
  20.     public MessageBroker processBeforeStartup(MessageBroker broker) {  
  21.         return broker;  
  22.     }  
  23. }  


注册这个Processor: 
Java代码  收藏代码
  1. <flex:message-broker>  
  2. <flex:config-processor ref="myConfigProcessor" />  
  3. </flex:message-broker>  
  4. <bean id="myConfigProcessor" class="com.example.MyDestinationCountingConfigProcessor" />  

【2.7. 向Flex端传送后台执行时的exception错误信息】 
BlazeDS集成j2ee时,flex端通过rpc httpservice等调用时,当产生遇到错误抛出exception时,会抛出flex.messaging.MessageException. 
但是BlazeDS不会把这个exception传到flex端,而只告诉flex端 "Server.Processing" error. 
通过实现org.springframework.flex.core.ExceptionTranslator这个接口,并在application-config.xml里面配置后,就可以达到这个目的,举例如下: 
Java代码  收藏代码
  1. <!-- Custom exception translator configured as a Spring bean -->  
  2. <bean id="myExceptionTranslator" class="com.foo.app.MyBusinessExceptionTranslator"/>  
  3. <flex:message-broker>  
  4. <flex:exception-translator ref="myExceptionTranslator"/>  
  5. </flex:message-broker>  
原创粉丝点击