zoukankan      html  css  js  c++  java
  • Flex LCDS 与 spring 框架的整合说明

    原帖:http://www.riachina.com/showtopic.aspx?topicid=8723&page=3#41843
    想知道这个原理先要从事务概念说起了

    我们将一组有业务逻辑,原子性不可分离的操作集合称为事务,因此事务的要素就是有一个开始和结束,如果没有成功的到达结束点,那么中间做的所有操作将会被认为是一个无效的操作(取消或者回滚)。

    在 业务逻辑中,我们常常会定义某些service做一些局部性操作,在业务层再将他们组合起来定义成某一个事务方法,成为一个有业务逻辑的操作,如果不采用 事务控制,那么势必一个事务方法的开头和结尾必须写上,startTransaction和commitTransaction这样的语句。这样也未尝不 可,但是如果一个庞大的项目,对于开发人员来说,有时候没必要让其充分了解业务上的事务操作,甚至在有些情况下,他根本不能掌握一些和事务类似需要被控制 的状态,典型的比如持久层的访问状态。

    这些重复的、有规律的、无需人为或业务类来控制的、甚至是人难以掌握的,可以交给系统框架来处理。

    事务管理就是利用了aop,当你注册某一个类交由事务管理器去管理时(拦截器),他会在调用你注入的方法之前切入一个start标记,在调用完成后切入一个end标记,之间的方法他可以try起来,这样当成功执行到end时,就会执行事务提交。

    同样的道理,这种aop还可以应用于任何框架设计上,比如对于操作记录的log,权限的控制、dto、数据序列化转换、通讯控制等等上去,即在你注册的切入点就执行你定义的操作(拦截器)。

    这就是spring的ioc。

    刚 是说的aop设计上的原理,底层是如何实现的每种aop应用都有不同,就拿spring来说,他是针对class文件字节码来操作的,实际上,你写的代码 在注入之后,spring就会根据你注入的信息,去找对应的类的字节码文件,并进行修改,重新生成新的class文件。

    这样来说就有点类似hack行为,但是由于这个技术很成熟,且很早被人所接受,这种hack行为也被证实为是一种非常独到的程序设计。

    原 理说清楚后,再来理解你使用jotm就不难了,当你定义了事务工厂类之后,就可以通过spring是委派了一个事务管理器,在你的代码中这个事务管理器就 是org.objectweb.jotm.UserTransactionFactory,spring会将该类管理事务的方法切入进你注入的类,去执行 hack操作,将你注入的类的方法前打上start和end标记方法,当执行被注入方法成功时,最终执行该事务管理器中的事务提交方法。

    因此你的问题,你问是谁调用了他,实际就是你自己注入的类调用了他,只不过,你这个类被黑了(当然是你配置的)。

    那么再看你遇到的问题,根源在于,spring和fms都是采用了aop拦截机制的,fms的aop应用于我刚才说到的“远程调用和数据序列化转换”。

    1.远程调用:通过一个messagebreak监听所有的请求,当remoteobject请求某个java远程方法时,messagebreak就会去直接执行java里的remoteobject
    2.数据序列化:他将你方法返回的java数据对象,转换成amf协议里的二进制数据并return出来,最终输出。

    再来说spring,刚刚说到,你委派了一个事务工厂去管理事务,但是,哪些bean需要被注入呢?空头司令可是没什么价值的。

    实 际上,springframework将这一系列的“增值服务”封装进自己的bean里去了,也就是为什么,在spring容器里需要getbean来获 得一个实例,而不要自己去new,这样,就能跟这个对象去增加很多“增值服务”。在你替spring指派了transactionmanager后,还需 要让spring给他可以管理的对象,这样才能让你的类享受增值服务。

    然而,你现在整合两套独立的aop框架,fms的aop可以不用理 会spring的aop,独自切入,这样就导致,spring虽然给你的class打上了start或者end的标记,但是这个bean并没有从 spring容器中产生,而是由fms的messagebroker去new出来的,导致不能享受“增值服务”,说白 了,TrasnactionManager必须被spring调用,比如他给这个manager设置了某些参数。
    而fms得到的bean不是由spring容器里的,自然就无法享受“增值服务”了。

    问题找到了,但是如何解决呢?

    在remote-config.xml配置里,映射一个java对象是这么写的

    <destination id="userService">
    <properties>
    <source>com.test.service.userService</source> 
    </properties>
    </destination>



    如果这样,userService就会直接被ro访问,从而脱离spring容器。如果你要对某个java类实现自己定义的切入,你可以使用工厂配置,即我需要在ro访问前,从spring里去getbean
    那么就可以这么改一下

    <destination id="userService">
    <properties>
    <factory>springFactory</factory> 
    <source>com.test.service.userService</source> 
    </properties>
    </destination>



    这个springFactory是在service-config.xml里配置的,

    <factories>
    <factory id="springFactory" class="com.test.factory.SpringFactory" /> 
    </factories>



    这样,就定义了一个SpringFactory类去执行在userService切入之前的操作,即,我们要实现从从spring容器中去取得bean。
    该factory需要实现FlexFactory接口。实现createFactoryInstance方法和lookup方法

    public FactoryInstance createFactoryInstance(String id, ConfigMap properties){
    SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties);
    instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
    return instance;
    }
    public Object lookup(FactoryInstance inst)  {
    SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
    return factoryInstance.lookup();
    }



    createFactoryInstance方法中用到了一个SpringFactoryInstance ,他是继承自FactoryInstance的

    class SpringFactoryInstance extends FactoryInstance
    {
    SpringFactoryInstance(SpringFactory 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;

    }

    }



    这样,访问ro时,就会通过工厂模式去从spring容器中getBean了

    //相关完整的一个spring整合可以从google code的svn里下载http://flex-java.googlecode.com/svn/trunk/

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959718.html
Copyright © 2011-2022 走看看