上篇中show了一下近期作的demo页面,现在讲一讲我使用的架构:
自己原来的项目架构是 WebWork2 + Spring + Hibernate,现在通过FLex替代了WebWrok2来表显视图层,而Flex与Spring通讯采用了BlazeDS这个开源免费的Flex服务程序。
BlazeDS是Adobe公司发布的免费开源产品,与该公司的另一款收费产品LCDS功能相近,应该是LCDS简化开源免费版。目前我通过RemoteObject的方式访问后台Service感觉比较方便。BlazeDS下载地址:http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+3
如何通过RemoteObject访问Spring管理的Bean,我参照另一篇教程文档 进行了设计与开发,在这篇文章中,用的是Adobe非免费Flex服务程序,只需要将LCDS中的flex.war换成BlazeDS中的flex.war就可以了。另外,这里有一篇“使用BlazeDS实现Java 和Flex 通信 ”的文章,讲解了如何在eclipse中配置Flex工程。
以下是一个Flex页面访问RemoteObject的代码:
- <? xml version = "1.0" encoding = "utf-8" ?>
- < mx:Application xmlns:mx = "http://www.adobe.com/2006/mxml" layout = "absolute" >
- < mx:Script >
- <![CDATA[
- import mx.rpc.events.ResultEvent;
- import mx.controls.Alert;
- private function callRO(str:String):void{
- Alert.show("flexSpringBeanTest");
- firstRO.say(str);
- firstRO.addEventListener(ResultEvent.RESULT,getROResult);
- }
- private function getROResult(e:ResultEvent) :void {
- Alert.show(e.result.toString());
- }
- //flexObjectTest
- ]]>
- </ mx:Script >
- < mx:RemoteObject id = "firstRO" destination = "flexSpringBeanTest" />
- < mx:TextInput x = "109" y = "28" id = "input" text = "hello!" />
- < mx:Button x = "270" y = "28" click = "callRO(input.text)" label = "请求" />
- </ mx:Application >
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Script> <![CDATA[ import mx.rpc.events.ResultEvent; import mx.controls.Alert; private function callRO(str:String):void{ Alert.show("flexSpringBeanTest"); firstRO.say(str); firstRO.addEventListener(ResultEvent.RESULT,getROResult); } private function getROResult(e:ResultEvent) :void { Alert.show(e.result.toString()); } //flexObjectTest ]]> </mx:Script> <mx:RemoteObject id="firstRO" destination="flexSpringBeanTest"/> <mx:TextInput x="109" y="28" id="input" text="hello!"/> <mx:Button x="270" y="28" click="callRO(input.text)" label="请求"/> </mx:Application>
在remote-config.xml配置里,映射一个Spring管理的Bean是这么写的
- < destination id = "flexSpringBeanTest" >
- < properties >
- < factory > springFactory </ factory >
- < source > flexObjectTest </ source >
- </ properties >
- </ destination >
<destination id="flexSpringBeanTest"> <properties> <factory>springFactory</factory> <source>flexObjectTest</source> </properties> </destination>
在services-config.xml配置自定义的SpringFactory类,即我们要实现从从spring容器中去取得bean。
- < factories >
- < factory id = "springFactory" class = "cn.org.coral.core.flex.factory.FlexSpringFactory" />
- </ factories >
<factories> <factory id="springFactory" class="cn.org.coral.core.flex.factory.FlexSpringFactory" /> </factories>
这个工厂类的定义:
- package cn.org.coral.core.flex.factory;
- import flex.messaging.FactoryInstance;
- import flex.messaging.FlexFactory;
- import flex.messaging.config.ConfigMap;
- /**
- * 要对某个java类实现自己定义的切入,可以使用工厂配置,需要在ro访问前,从spring里去getbean<br>
- *
- * @author Libin
- *
- */
- public class FlexSpringFactory implements FlexFactory{
- @Override
- public FactoryInstance createFactoryInstance(String id, ConfigMap properties){
- SpringFactoryInstance instance = new SpringFactoryInstance( this , id, properties);
- instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
- return instance;
- }
- @Override
- public Object lookup(FactoryInstance inst) {
- SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
- return factoryInstance.lookup();
- }
- @Override
- public void initialize(String arg0, ConfigMap arg1) {
- // TODO Auto-generated method stub
- }
- }
package cn.org.coral.core.flex.factory;
import flex.messaging.FactoryInstance;
import flex.messaging.FlexFactory;
import flex.messaging.config.ConfigMap;
/**
* 要对某个java类实现自己定义的切入,可以使用工厂配置,需要在ro访问前,从spring里去getbean<br>
*
* @author Libin
*
*/
public class FlexSpringFactory implements FlexFactory{
@Override
public FactoryInstance createFactoryInstance(String id, ConfigMap properties){
SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties);
instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
return instance;
}
@Override
public Object lookup(FactoryInstance inst) {
SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
return factoryInstance.lookup();
}
@Override
public void initialize(String arg0, ConfigMap arg1) {
// TODO Auto-generated method stub
}
}
该factory需要实现FlexFactory接口。实现createFactoryInstance方法和lookup方法
- package cn.org.coral.core.flex.factory;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.NoSuchBeanDefinitionException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import flex.messaging.FactoryInstance;
- import flex.messaging.config.ConfigMap;
- import flex.messaging.services.ServiceException;
- public class SpringFactoryInstance extends FactoryInstance
- {
- SpringFactoryInstance(FlexSpringFactory factory, String id, ConfigMap properties)
- {
- super (factory, id, properties);
- }
- public Object lookup()
- {
- //这就是从spring容器中getbean了
- ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(flex.messaging.FlexContext.getServletConfig().getServletContext());
- String beanName = getSource();
- try
- {
- return appContext.getBean(beanName);
- }
- catch (NoSuchBeanDefinitionException nexc)
- {
- ServiceException e = new ServiceException();
- throw e;
- }
- catch (BeansException bexc)
- {
- ServiceException e = new ServiceException();
- throw e;
- }
- }
- }
package cn.org.coral.core.flex.factory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import flex.messaging.FactoryInstance;
import flex.messaging.config.ConfigMap;
import flex.messaging.services.ServiceException;
public class SpringFactoryInstance extends FactoryInstance
{
SpringFactoryInstance(FlexSpringFactory factory, String id, ConfigMap properties)
{
super(factory, id, properties);
}
public Object lookup()
{
//这就是从spring容器中getbean了
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(flex.messaging.FlexContext.getServletConfig().getServletContext());
String beanName = getSource();
try
{
return appContext.getBean(beanName);
}
catch (NoSuchBeanDefinitionException nexc)
{
ServiceException e = new ServiceException();
throw e;
}
catch (BeansException bexc)
{
ServiceException e = new ServiceException();
throw e;
}
}
}
后台service的定义:
- package cn.org.coral.sample.flex.manager;
- public class FlexObjectTest {
- public String say(String str){
- return "say : " + str;
- }
- }
package cn.org.coral.sample.flex.manager;
public class FlexObjectTest {
public String say(String str){
return "say : " + str;
}
}
spring-context.xml的配置
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- < beans >
- < bean id = "flexObjectTest"
- class = "cn.org.coral.sample.flex.manager.FlexObjectTest" >
- </ bean >
- </ beans >
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="flexObjectTest" class="cn.org.coral.sample.flex.manager.FlexObjectTest"> </bean> </beans>