背景技术
随着企业信息化及自动化程度的提高,企业内信息业务对IT系统的依赖程度也越来越高。但企业IT部门与具体业务部门之间存在矛盾,主要表现为:IT部门的软件开发人员擅长编写代码,针对具体业务部门提出的要求,使用不同的模块,用硬代码将业务规则固化起来实现;但对于具体业务人员来说,很难从详细的代码文档中获知相关的信息,包括代码创建日期、创建人、相应代码对应的具体业务等等,因此,具体业务人员只能通过已经编辑好的程序进行执行而无法管理;当某些业务规则需要变化时,具体业务人员也不得不借助IT部门的人员进行修改。这种情况一方面带来了IT部门人员工作量的增加,以及部门之间进行反复导致的效率降低;另一方面,一些企业内部规则的变化需要完全展示给IT部门的人员,增加了泄密的风险。
因此,模仿将数据从业务系统中剥离出来,单独作为数据库存在的做法,在IT系统中出现了专门把变化的业务规则从业务系统中提取出来作为规则库,通过规则引擎和规则触发接口独立的形成规则系统的情况,其目的是把变化的需求从业务系统中分离出来。在软件技术上,主要有两种方法实现上述规则系统与业务系统的分离:
第一种:规则系统作为整个业务软件系统的一个子系统来实现,比如网络防火墙中的过滤规则,网管系统中的报警规则,邮箱收发工具(如Outlook)中邮件规则,都是作为各自业务系统中的子系统存在的;
第二种:规则系统是独立的,它和业务系统之间通过规则触发接口来连接。比如用来搭建电子商务平台的ILog软件组件、使用Java开发的基于Rete算法的规则引擎Drools等规则系统。参见图1,为ILog中规则系统和业务系统的框图,当需要规则服务时规则触发接口启动,通过规则引擎调用规则库的相关规则,实现业务处理并返回处理结果。
上述两种规则系统的触发方法,目前都是采用在业务系统中嵌入事件报送代码来实现,比如ILog以及Java规范JSR94中都是如此,具体方式为:在业务系统插入手工编写的事件报送代码,来报送事件给规则系统,如下示例:
public class CustomerDAO{public int add(Customer cust){Rule.fire("rulepackage","before",cust);Try{......//其它业务代码}finally{Rule.fire("rulepackage","after",cust);}}} |
通过在类定义“CustomerDAO”的程序代码中嵌入事件报送代码“Rule.fire”程序段,实现在业务系统执行过程中,报送事件“CustomerDAO”给规则系统,从而实现规则系统的触发。通过这种方式,IT人员只需要搭建业务框架,并嵌入事件报送代码,而将真正的逻辑规则放在规则系统中,因此系统结构变得简单;同时,规则系统中相关的规则库中存放小的程序逻辑段,该逻辑段可以通过描述性语言编写,可以被有效地管理,如规则查询、权限控制、实时部署、规则共享、版本管理等,因此业务人员有机会来接触,并通过工具来查询、修改甚至部署他的规则。
但是,上述实现规则系统触发的方法同时具有以下缺陷:
第一、在业务系统的代码中到处插入这样的事件报送代码将消耗开发人员大量的劳动和时间;
第二、在代码中需要固定规则集编码(或称为规则库编码),需要固定输入参数对象,需要固定返回结果对象,这些使得相关修改规则库、输入参数对象、返回对象结构的工作非常困难,难以期望在业务规则被修改时迅速实现业务系统中的相应变化;
第三、一旦业务系统部署之后,对应部分插入的代码就很难改变,当业务规则发生变化时,对应的业务系统中的接口和参数等就需要发生变化,即使不考虑即时性,修改这种像蜘蛛网一样布满各个模块的代码也是难以想象。
同时,在目前实现规则系统触发的方法中,除了采用上述的手工代码进行触发以外,在规则系统中定义事件类型和具体事件所用到的参数也是手工设定的,具体方式为:在规则系统中,使用系统提供的界面和配置文件信息定义事件类型和具体事件。
综上所述,现有通过对业务系统和规则系统进行分离来实现规则系统触发的方法主要有以下缺点:
1、需要在业务代码中手工插入事件报送代码,增加开发人员工作量,并使得触发所需耦合度加大;
2、业务系统开发人员需要在系统开发阶段对业务规则有一定了解,包括所用规则集及参数,增加了开发人员难度;
3、后期规则发生变化,比如需要修改规则库或修改输入输出参数时,仍然需要修改业务系统中的相应代码,使得需求响应速度降低,同时耗费了大量的劳动;
4、开发业务系统代码和定义规则系统规则库属于重复劳动,容易参数错误或遗漏。
发明内容
本发明的一个目的是针对上述现有技术中的缺陷,提供一种实现规则系统触发的系统,通过加入对业务事件进行过滤的模块,实现无需手工编写事件报送代码的目的。
本发明的另一目的是针对上述现有技术中的缺陷,提供一种实现规则系统触发的方法,通过在业务系统中对报送事件进行过滤,避免在编写业务系统代码过程中进行规则开发定义工作,有利于进行规则调整,降低错误率,减少重复性工作,实现业务系统和规则系统的分离。
为实现上述目的,本发明提供了一种实现规则系统触发的系统,包括一业务系统及与所述业务系统连接的一规则系统,所述业务系统中的至少一个业务模块与一事件处理器连接,用于报送业务事件及参数数据;所述事件处理器与一触发事件类型列表模块连接,用于接收所述业务模块报送的业务事件及参数数据,并根据所述触发事件类型列表模块中的触发事件类型信息过滤触发事件;所述事件处理器还与所述规则系统连接,用于封装和发送所述触发事件给所述规则系统。
为实现上述目的,本发明还提供了一种实现规则系统触发的方法,包括以下步骤:
步骤1、业务模块加载时,向所述业务模块中自动加入事件报送代码;
步骤2、业务模块报送业务事件到事件管理器;
步骤3、所述事件管理器根据触发事件类型列表模块中的触发事件类型信息,判断所述业务事件是否为能够触发规则系统的触发事件,是则执行步骤4,否则向业务模块返回无效指令并结束;
步骤4、所述事件管理器发送所述触发事件至规则系统;
步骤5、所述规则系统搜索匹配所述触发事件的规则定义,根据所述规则定义及具体参数数据处理所述触发事件,并将所述触发事件的处理结果返回给所述事件管理器;
步骤6、所述事件管理器将所述处理结果返回给所述业务模块,结束。
由上述技术方案可知,本发明基于现有的自定义类加载技术或Java语言代理类技术,采用事件管理器进行触发事件过滤,具有以下有益效果:
1、对触发事件在业务系统之外进行过滤,业务系统开发人员无需在系统开发阶段对业务规则进行了解,因此无需进行重复性的规则开发定义工作;
2、业务规则在规则系统开发阶段独立进行,便于修改,同时对规则参数的变化能够实现即时响应;
3、自动报送触发事件,无需手工编写事件报送代码,降低了工作量和系统耦合度要求;
4、实现了业务系统和规则系统的分离。
下面通过附图和实施例,对本发明的技术方案做进一步的详细描述。
具体实施方式
为了实现把业务系统中的触发事件传递到规则系统,需要在业务系统中加入事件报告部件,并对事件进行统一处理归口,再传递到规则系统。为了减少冗余事件的传递,规则系统要能够把需要的事件类型告之业务系统,不需要的事件则不捕获不传递。本发明实现规则系统触发的系统的实施例1如图2所示,由业务系统1和规则系统2组成,业务系统1具体包括多个业务模块11、一事件管理器12和触发事件类型列表模块13,业务模块11以及触发事件类型列表模块13分别与事件管理器12连接;规则系统2具体包括规则触发接口21、规则引擎22和规则库23。
其中,编号从1到N的业务模块11分别执行各自功能操作,比如处理outlook的业务模块。该业务模块11可使用计算机语言编写,比如Java;也可以是web形式的应用程序。该计算机语言或应用程序搭建了功能框架,涉及到具体规则限定的内容通过自定义类嵌入。
在本发明中,编号从1到N的业务模块11加载时,Java环境下启动一个加载线程,通过Java自定义类加载方法或Java语言代理类(即Java字节码指令,Java Bytecode Instrumentation,简称Java BCI)方法在所述业务模块11中自动加入事件报送代码。
当业务模块11执行至自定义类代码或者其他跳出或中断操作代码等业务事件时,将相关代码或Web形式的应用程序传送给事件管理器12。
事件管理器12对业务事件进行判断过滤,具体为:事件管理器12检查触发事件类型列表模块13,根据模块13中的触发事件类型信息进行判断,如果该业务事件为能够触发规则系统的触发事件,由事件管理器12将该触发事件及参数数据通过规则触发接口21传送给规则系统2。
由于在一个完整的业务系统1中,具有不同层次的触发事件存在,从网络硬件底层一直到前端的用户界面和用户操作事件,如图3所示。比如网络防火墙中的规则系统关注的是网络事件、计算机上的杀毒软件系统可能关注的是一些操作系统事件、其它层次也类似。一般规则系统都不会关注所有的事件,而会专注于某一层。对于企业的一个业务系统1(如电信的BOSS系统),则关注的是业务系统框架、业务模块及用户界面的一些事件,则这些事件就作为触发事件类型信息记载于规则系统2,并可被随时修改限定。可由规则系统2同步触发事件类型信息至触发事件类型列表模块13中,也可以由系统管理人员添加入触发事件类型列表模块13。
对于触发事件,事件管理器12中按照规则触发接口21要求的数据格式封装该触发事件并发送。
规则触发接口21将触发事件接收至规则系统2中,由规则引擎22根据具体触发事件的类型,在规则库23中搜索与该类型相匹配的规则定义,根据匹配的规则定义和参数数据进行处理,并返回处理结果给事件管理器12。业务模块11根据事件管理器返回的结果执行当前类,并继续向下执行业务代码。
该规则库23用于保存触发事件类型信息以及与所述触发事件类型信息相关联的具体规则定义。为了完成规则的定义,需要知道规则所依赖的触发事件的具体参数数据,如结构数据等。例如在增加客户的方法中,规则系统就需要事先了解“客户”这个事件类型,“客户”类型的相关参数数据来进行处理。
参数数据的定义可以采用传统的方法,在规则系统中逐个的定义这样的参数数据:开发人员首先在规则系统中手工的添加客户增加事件定义和客户类的参数数据,然后给规则定义人员使用。
进行参数数据定义的更好的方法是利用XDoclet方法或者java 5.0中新的注解方法来完成参数属性信息数据的定义。通过使用这两种方法,可以实现在编写业务模块代码时,通过添加注释信息,就同时完成了规则所需参数数据的定义。示例如下:
public class CustomerDAO{/***@ruletype("xxx.xxx.customer.add")*@ruleparament("xxx.xxx.Customer")*/public int add(Customer cust){......//其它业务代码return 0;}} |
/***@class("xxx.xxx.Customer","客户")*@classattribute("id","客户ID")*@classattribute("name","客户名称")*@其它属性...*/public class Customer{String id;String name;String other//其它属性} |
在编译打包该业务模块时,规则系统2就在编译过程中对源代码进行分析,提取规则所需参数数据信息,加入到规则库23中。这样就无需在规则系统2中重新进行定义,同时,对应的客户增加事件也作为触发事件类型信息被存储至规则系统2中。则规则系统2无须分别定义不同的繁杂参数数据以应付各种情况,而可以直接从待处理的触发事件代码的注释信息中提取需要的参数数据。
本发明的实现规则系统触发的系统的实施例2,如图4所示,由业务系统1和规则系统2组成,业务系统1具体包括多个业务模块11、一事件管理器12和触发事件类型列表模块13,规则系统2具体包括规则触发接口21、规则引擎22和规则库23和数据同步模块24,规则系统2中规则库23通过数据同步模块24向业务系统1中的触发事件类型列表模块13同步触发事件类型信息。。
该触发事件类型列表模块13中的触发事件类型信息由规则系统2进行同步,同步方式为通过数据同步模块24进行规则库23中触发事件类型信息与触发事件类型列表模块13中触发事件类型信息的同步;可以定期更新,也可以在规则库23中的触发事件类型信息被管理人员修改后即时进行更新。
基于上述系统的实现规则系统触发的方法的实施例,参见图5,包括以下步骤:
步骤1、执行功能操作的业务模块加载;
步骤2、向所述业务模块中自动加入事件报送代码,比如可由Java线程来执行自动加入,由于无需手工编写事件报送代码,降低了工作量和系统耦合度要求;
步骤3、业务模块报送业务事件到事件管理器;
步骤4、所述事件管理器根据触发事件类型列表模块中的触发事件类型信息,判断所述业务事件是否为能够触发规则系统的触发事件,是则执行步骤5,否则执行步骤6;
本步骤中通过将触发事件的判断从业务模块中分离出来,使业务系统开发人员无需在系统开发阶段对业务规则进行了解,因此无需进行重复性的规则开发定义工作;
步骤5、所述事件管理器将所述触发事件封装发送至规则系统;
步骤6、所述规则系统搜索匹配所述触发事件的规则定义,根据所述规则定义及参数数据处理该触发事件,并将所述触发事件的处理完成结果返回给事件管理器;其中,参数数据可以由开发人员手工添加,也可以通过在触发事件中添加注释实现;对于通过在所述业务事件中添加注释信息定义所述业务事件的参数数据的情况,该注释信息为利用XDoclet方法或Java注解方法添加到所述触发事件中,因此无须在规则系统中对具体的参数进行定义,减少了工作量,并降低了开发难度;
步骤7、事件管理器将所述处理完成结果返回给所述业务模块,结束;
步骤8、事件管理器向业务模块返回无效指令,结束。
通过上述步骤,实现了业务系统和规则系统的分离。
其中,步骤2之前,可以利用XDoclet方法或者java 5.0中新的注解方法(Java Annotation)来完成参数属性信息数据的定义。
步骤2中的自动加入事件报送代码可以通过Java语言环境下的线程实现。比如Java中使用非常广泛的拦截技术:自定义类加载方法和Java 5.0中的Java BCI方法。
对于Java自定义类加载方法,是通过继承系统的ClassLoader类,实现自己定义的加载类。在自己定义的加载类,可以实现对类的加载来源和加载的内容进行控制,目前应用的有为了防止反编译而实现的类加密技术。在这里也可以使用自定义类加载技术来在类加载的时候对所加载的类进行修改,在需要监听的类方法中自动的加入事件报送代码。
而Java BCI方法位于可以实现自己的代理类的java.lang.instrument包中。在代理类的premain方法中,注册自己的MyClassFileTransformer类。在MyClassFileTransformer类中,实现了接口ClassFileTransformer,该接口通过一个方法transform,传入参数是类名和类的字节码,如果需要修改字节码,只要把修改后的字节码返回,否则返回空或把原字节码返回即可。具体为在运行java程序时,加入参数javaagent参数(而且可以指定多个),如在ant运行脚本中这样写:
<target name="Tester"><java classname="em.Tester" dir="bin" fork="true"output="dist/output.txt"><jvmarg value="-javaagent:../dist${ant.project.name}.jar"/></java></target> |
除了对业务代码进行这样方式的拦截外,也可以对Web形式的应用程序建立拦截,比如对所有提交的表单进行拦截,只要继承javax.servlet.Filter接口,实现自定义的Filter,然后在web.xml中注册接口。
参见图6,是业务模块加载时采用Java BCI方法自动加入事件报送代码的示意图,特别是根据加入的注释自动加入事件报送代码,这里的类转换器就起到了一个线程的作用。
步骤3中所述发送之前还包括:所述事件管理器按照规则触发接口要求的数据格式对所述触发事件进行封装。
步骤4可具体为:
步骤41、所述规则系统接收所述触发事件;
步骤42、所述规则系统的规则引擎根据所述触发事件类型信息,在规则库中搜索与所述触发事件类型信息相匹配的规则定义;
步骤43、所述规则系统的规则引擎根据所述规则定义及参数数据进行所述触发事件的处理,该处理方法采用现有规则系统的处理方法,比如Rete算法;
步骤44、所述规则系统的规则引擎返回所述处理结果给所述事件管理器。
在本实施例中,规则系统定时更新所述业务系统中的触发事件类型信息,或者规则系统在触发事件类型信息修改后更新所述业务系统中的触发事件类型信息。更具体的,规则系统更新的可以是业务系统中触发事件类型列表模块中的触发事件类型信息。
如图7所示,为实现规则系统触发的方法的一采用Java自定义类加载技术的实施例,包括以下步骤:
步骤101、规则系统通过数据同步装置更新触发事件类型列表模块中触发事件类型列表;
步骤102、执行功能操作的业务模块加载,其中包括CustomerDAO类,具有如下代码:
public class CustomerDAO{public int add(Customer cust){......//其它业务代码return 0; |
步骤103、Java线程采用Java自定义类加载技术向该CustomerDAO类中加入自动报送代码,如下:
public class CustomerDAO{public int add(Customer cust){Rule.fire("rulepackage","before",cust);try{......//其它业务代码}finally{Rule.fire("rulepackage","after",cust);}}} |
加入后和在java源代码中加入的方法一样,但却无需手工编程实现;
步骤104、当业务模块执行到该CustomerDAO类时,将其报送到事件管理器;
步骤105、事件管理器封装并调用规则触发接口将所述触发事件发送至规则系统;
步骤106、所述规则系统通过规则触发接口接收该触发事件;
步骤107、所述规则系统调用规则引擎,根据所述触发事件类型信息在规则库中搜索与所述触发事件类型信息相匹配的规则定义;
步骤108、所述规则系统根据所述规则定义及参数数据进行触发事件的处理,该参数数据可以为手工添加;
步骤109、所述规则系统将处理完成结果返回给所述事件管理器;
步骤110、事件管理器将所述处理完成结果返回给所述业务模块。
其中,在步骤103之前,还可以通过Java环境向业务模块添加注释信息,从而定义业务事件的具体参数数据,比如事件拦截可以使用java中的JVMPI和JVMTI技术,使用自定义的注释标记语法。
如图8所示,为本发明实现规则系统触发的方法的又一实施例,本实施例中利用XDoclet技术进行业务模块的注释,包括以下步骤:
步骤201、执行功能操作的业务模块加载;该业务事件为使用XDoclet技术进行注释信息添加的类CustomerDAO,该业务事件中包括注释信息定义的参数数据;
public class CustomerDAO{/***@ruletype("xxx.xxx.customer.add")*@ruleparament("xxx.xxx.Customer")*/public int add(Customer cust){......//其它业务代码return 0;}} |
/***@class("xxx.xxx.Customer","客户")*@classattribute("id","客户ID")*@classattribute("name","客户名称")*@其它属性...*/public class Customer{String id;String name;String other//其它属性} |
步骤202、Java进程向业务模块中自动加入事件报送代码,可参见上一实施例的步骤103;
步骤203、业务模块报送所述业务事件到事件管理器;
步骤204、事件管理器检查触发事件类型列表,判断该类CustomerDAO为能够触发规则系统的触发事件;
步骤205、事件管理器将类CustomerDAO封装并发送至规则系统;
步骤206、规则系统通过规则触发接口接收该触发事件,该触发事件中包含了参数数据;
步骤207、规则系统调用规则引擎根据所述触发事件类型信息,在规则库中搜索与所述触发事件类型信息相匹配的规则定义;
步骤208、规则引擎根据所述规则定义及触发事件中的参数数据进行触发事件的处理,该处理方法为现有规则系统进行触发事件处理的方法;
步骤209、所述规则系统返回处理完成结果给所述事件管理器;
步骤210、事件管理器将所述处理完成结果返回给所述业务模块。
其中,步骤201中,也可以利用Java注解技术添加所述注释信息。
在本实施中,如果系统工作人员对规则系统中的触发事件类型列表进行了修改,则规则系统即时进行触发事件类型列表模块中触发事件类型列表的更新;同时,规则系统也定时进行触发事件类型列表模块更新。
最后所应说明的是,以上实施例仅用以说明本发明的技术方案而非限制,尽管参照较佳实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明技术方案的精神和范围。