由于 BlazeDS 需要将 Java 接口 FlexService 暴露给 Flex 前端,因此,我们在配置文件 remoting-config.xml 中将 FlexService 接口声明为一个服务:
清单 6. 定义 flexService 服务
服务名称通过 destination 的 id 属性指定,Flex 前端通过该服务名称来进行远程调用。scope 指定为 application,表示该对象是一个全局对象。
然而,按照默认的声明,BlazeDS 会去实例化 FlexService 对象。对于一个 Java EE 应用来说,通常这些服务对象都是被容器管理的(例如,Spring 容器或 EJB 容器),更合适的方法是查找该服务对象而非直接实例化。因此,需要告诉 BlazeDS 通过 Factory 来查找指定的 FlexService 对象,修改配置如下:
清单 7. 通过 factory 定义 flexService
现在,Flex 如何才能通过 BlazeDS 调用 FlexService 接口呢?由于 FlexService 对象已经被 Spring 管理,因此,我们需要编写一个 FlexFactory 告诉 BlazeDS 如何找到 Spring 管理的 FlexService 的实例。flexFactory 在 services-config.xml 中指定:
清单 8. 定义 flexFactory
FlexFactoryImpl 实现了 FlexFactory 接口,该接口完成两件事情:
1、创建 FactoryInstance 对象;
2、通过 FactoryInstance 对象查找我们需要的 FlexService.
因此,需要一个 FactoryInstance 的实现类,我们编写一个 SpringFactoryInstance,以便从 Spring 的容器中查找 FlexService:
清单 9. SpringFactoryInstance class
class SpringFactoryInstance extends FactoryInstance { private Log log = LogFactory.getLog(getClass()); SpringFactoryInstance(FlexFactory factory, String id, ConfigMap properties) { super(factory, id, properties); } public Object lookup() { ApplicationContext appContext = WebApplicationContextUtils. getRequiredWebApplicationContext( FlexContext.getServletConfig().getServletContext() ); String beanName = getSource(); try { log.info("Lookup bean from Spring ApplicationContext: " + beanName); return appContext.getBean(beanName); } catch (NoSuchBeanDefinitionException nex) { ... } catch (BeansException bex) { ... } catch (Exception ex) { ... } } } |
FlexFactoryImpl 负责实例化 SpringFactoryInstance 并通过 SpringFactoryInstance 的 lookup() 方法查找 FlexService 接口对象:
清单 10. FlexFactoryImpl class
public class FlexFactoryImpl implements FlexFactory { private Log log = LogFactory.getLog(getClass()); public FactoryInstance createFactoryInstance(String id, ConfigMap properties) { log.info("Create FactoryInstance."); SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties); instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId())); return instance; } public Object lookup(FactoryInstance instanceInfo) { log.info("Lookup service object."); return instanceInfo.lookup(); } public void initialize(String id, ConfigMap configMap) { } } |
以下是 BlazeDS 查找 FlexService 接口的过程:
1、BlazeDS 将首先创建 FlexFactory 的实例—— FlexFactoryImpl;
2、当接收到 Flex 前端的远程调用请求时,BlazeDS 通过 FlexFactory 创建 FactoryInstance 对象,并传入请求的 Service ID.在这个应用程序中,被创建的 FactoryInstance 实际对象是 SpringFactoryInstance;
3、FactoryInstance 的 lookup() 方法被调用,在 SpringFactoryInstance 中,首先查找 Spring 容器,然后,通过 Bean 的 ID 查找 Bean,最终,FlexService 接口的实例被返回。
注意到 destination 的 id 并没有写死在代码中,而是通过以下语句获得的:
清单 11. 获取 destination 的 ID
properties.getPropertyAsString(SOURCE, instance.getId()) |
Property 的 SOURCE 属性由 BlazeDS 读取 XML 配置文件获得:
清单 12. 配置 destination 的 id
如果您没有使用 Spring 框架,也不要紧,只需修改 FactoryInstance 的 lookup() 方法。例如,对于一个 EJB 来说,lookup() 方法应该通过 JNDI 查找返回远程接口。无论应用程序结构如何,我们的最终目标是向 BlazeDS 返回一个 FlexService 的实例对象。
① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;
② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。