在用户修改了领域对象的值后,我们有时需要记录下用户的改动。比如对一些关键业务对象的改动有时往往需要发邮件通知客户。有时用户可能想查阅所有历史的改动,甚至有可能会改回原先的值。
领域逻辑关系往往比较复杂,这时我们会使用到ORM Framework。本文以toplink为例,讲述如何利用toplink编写一个完成此功能的简易Framework,我们暂且把它称为ActionMemed。
我们先来看一下大体的流程:
l 我们获得用户修改信息通常有两种方式,一种是被动的监听,另一种主动的通知。被动的监听就是framework订阅所关心领域对象的修改,主动通知是application主动的将修改之前和之后的对象通知framework。
l Framework接着从整个对象的树结构中找出用户所关心的某个特定的字段或者字段的组合,生成actionRecord。ActionRecord是描述用户对领域对象修改的数据结构,会包括用户修改的原因,修改者,修改的时间,修改的字段或者组合,修改前后的值等等信息。
l 在ActionRecord生成好之后,会将它记录到DB,发邮件通知用户或者通过JMS通知其他Application。
有了基本的概念后,看一下整体的结构:
Registry: 在TopLink上注册ActionListener。一旦在TopLink上检测到业务对象的改动就会调用ActionService,生成ActionRecord并调用相关的ActionRecorder。
ActionListener:TopLink的SessionListener,每次会话都会调用。我们在这里实现了preCommit方法,在UnitOfWork提交之前,捕捉用户的所有修改,并从中选取出用户所关心的对象的变动。
ActionService:当ActionListener从TopLink中获得到改动的对象,就会调用ActionService生成ActionRecord,并通知相关的Recorder,可能是Log到DB。如果用户是通过主动的方式传入新老两个对象就不需要Listener,直接调用ActionService,将新老对象或者新对象和ValueDistiller作为参数传入,
ValueDistiler:根据当前的新对象,萃取出老对象。TopLink就可以根据当前UnitOfWork中的新对象获取原始对象。方法是:
public Object getOriginalVersionOfObject(Object workingClone)
|
Expression:ActionMemed相关的配置数据,由ExpressionParser解析出来后就会cache在内存中。这个配置可以是文件,或者DB配置。只要能描述清楚就行。文件配置我们直接利用spring bean。
ActionConstructor:Listener从TopLink ChangeSet中拿到的只是有改动的对象。而我们关心的只是对象上某个Field或者它引用的某个对象的Field,比如说Employee有PhoneNumber List,PhoneNumber有个属性是areaCode,可能我们只关心areaCode值的更改,就只需要记录areaCode的更改,并且通知客户。所以我们需要根据用户配置对新老对象进行对比,比较是否有关注的属性被用户更改了。并且构建ActionRecord。比较的方法我们可以用JXpath, Xpath的表达能力很强,而且还可以自定义函数,在自定义扩展函数里用户可以对字段进行组合处理,从而生成它们自己想要记录的值。
ActionRecorder:当Action构建完成后,ActionRecorder就要将它通知客户,用JMS发给其他项目或者记录到DB。用户可以配置多个ActionRecorder。
MemedEventListener,让用户在ActionRecorder调用之前和之后做一些额外的处理。比如说用户可能在之前对Action的数据结构加入一些定制信息。
上面介绍了ActionMemed的流程和相关模块的功能。其实在使用中,特别是一次修改很多业务对象的时候,处理Action时间会有点长,况且Action的处理也并不需要实时。所以Action还需要提供异步处理的功能。
将异步调用的模块图和先前的结构图进行比较会发现有两处不同:
ServiceTask: 实现Java Runnable接口,基本实现类似于先前图中的ActionService。
ObjectCloner: 如果我们使用TopLink,在异步的情况下,用户当前的UnitOfWork(事务)会先提交,提交之后,从TopLink中萃取的旧对象会被Merge成新对象,这时我们只能提前在UnitOfWork提交之前自己根据Expression的结构深Copy一份出来。
ActionAsyncService: 为异步设计的ActionService,利用ValueDistiller从UnitOfwork获得当前对象的原始clone,构建ServiceTask,将ServiceTask提交到ThreadPool,当task被执行时,就会调用ActionService,这时的ActionService重用了同步流程中的ActonService。
在下篇中,将会介绍几个注意点。
下篇地址:http://ldd600.iteye.com/blog/534043
- 大小: 19.2 KB
- 大小: 28.3 KB
分享到:
相关推荐
Servlet上下文和侦听器
首先简要介绍了网络侦听的原理及其潜在的安全隐患,讲述了侦听技术在Unix和Windows环 境下的几种实现技术;说明了如何检测侦听器的存在;最后提出了一种切实可行的、用来消除网络侦听 的方案。
8种加密狗侦听工具8种加密狗侦听工具8种加密狗侦听工具
<br>SerialTrace的界面美观精致,侦听、显示、仿真功能简捷易用,符合用户的操作和心理习惯。软件针对不同专业用户的关注内容,对信息进行分类,提供了 具有信息染色功能的多视图窗口供显示、分析使用,并提供...
关于时间控制侦听函数的频率比逐一侦听类型好。。
PHP-PayPal-IPN, 用于侦听和处理即时付款通知( IPN )的PHP 5类 PHP-PayPal-IPN一个用于 PHP 5的贝宝即时付款通知( IPN ) 类。在 PHP IPN脚本中使用 IpnListener 类处理发布数据。回发到贝宝,以及从PayPal解析响应。...
用于在服务器端侦听上传到服务器的数据。该工具是用C#编写的 ,使用的时候只要侦听端口号,以及要创建相应的数据库表。
socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器侦听socket 服务器...
这是关于jsp中比较重要的章节内容 主要是侦听器和过滤器的东西 里面有讲解很详细的 还有部分代码供大家参考
电力载波全侦听路由方案 电力载波全侦听路由方案
VS侦听sqlserver数据库表数据的变化
使用调度源发送 UDP 广播消息和侦听响应的框架。 要求 iOS 9.3以上版本,Swift 5.0 用法 包含一个示例应用程序,用于演示 UDPBroadcastConnection 的功能。 该示例可能不适用于您开箱即用,因为您需要有人在您的...
通过这款控件,用户可以轻松的完成功能上的扩充,以满足更多的需求。 这款控件的用途 SerialTraceAx ActiveX 控件能用于: 测试串口应用程序 开发串口侦听、拦截、监控程序 主要特点: 支持对信号事件的捕捉 (DTR, ...
多线程 TCP/IP 侦听器
局域网侦听工具.C:\TDDOWNLOAD\Spynet.rar
为提升无线传感器网络在能耗、时延以及动态适应负载方面的综合性能, 对几种典型MAC协议进行了分析, 提出了一种带冲突避免和流量自适应的LCT-MAC协议。在该协议中, 长前导码被划分为多个小前导码, 并嵌入目的节点地址...
网络侦听以及反侦听的原理和实现 监听 混杂模式
vu3 事件侦听和抛送模式,对跨模板使用的事件模式
利用windowsAPI实现windows7下话筒侦听的功能,waveInOpen等函数实现。
Rockey2侦听hid.dll 复制到要监听的目录下正常运行程序,会在c盘生成监听文件