APP下载

基于AOP理念的Struts2拦截器的研究与应用

2010-08-18卞世晖李龙澍陈圣兵

电子设计工程 2010年1期
关键词:拦截器插拔关注点

卞世晖,李龙澍,陈圣兵,李 浩

(1.安徽大学 计算机学院,安徽 合肥 230039;2.武汉理工大学 计算机学院,湖北 武汉430070)

面向对象编程OOP(Object-Oriented Programming)的开发方法是把软件系统看成各种对象的集合,采用抽象、封装、继承和多态的方法维护系统功能。但随着OOP技术应用实践的增多和应用范围的扩大,逐渐暴露出其不足和局限性。比如一个系统中有几十个或几百个数据库查询函数,每个地方都要求记录数据库查询的语句,OOP技术只能为每个函数增加记录日志,却没有更好的办法。而面向方面编程AOP(Aspect-Oriented Programming)技术则通过方法拦截解决,在每个方法调用前后或出现异常时记录日志信息[1]。

AOP是通过分离核心关注点和横切关注点,削弱二者之间的耦合度。利用AOP技术可对相关的横切关注点进行封装,从而保证横切关注点的复用,并根据需要适时增添、撤除、改变横切性关注点,而不影响核心关注点,提高系统的扩展性和灵活性。文中Struts2中的拦截器采用AOP的设计理念,通过定义、配置拦截器,拦截器可以按照“插拔”方式拦截相应的请求,配合业务控制器处理该请求。

1AOP的设计思想

拦截器采用AOP的设计理念,拦截是AOP的一种实现策略。AOP是针对OOP的局限性所提出的一种新的编程思想,是对OOP的补充和完善,它可以有效提高代码复用性,提高开发效率[2]。OOP技术引入封装、继承和多态性等概念建立一种对象层次结构,用以模拟公共行为的一个集合。但OOP不能为分散的对象引入公共行为。也就是OOP允许定义从上到下的关系,但并不适合定义从左到右的关系。例如安全验证、日志等功能往往水平散布在所有对象层次中,而与其所散布到的对象核心功能没有关系。这些散布在各处的代码被称为横切代码,在OOP设计中,它们造成大量代码的重复,不利于各个模块的复用。而AOP则可以减少系统中的重复代码,有效降低各模块间的耦合度,方便以后的维护和操作,它采用一种称为“横切”的技术,剖解开封装的对象内部,将影响多个类的公共行为封装到一个可重用模块,并将其称为“方面”。AOP代表一种横向的关系,在AOP中,将具有公共逻辑的、与其他模块的核心模块纠缠在一起的行为称为“横切关注点”,AOP就是要封装这些横切性关注点,以实现代码的复用性、灵活性和扩展性。

2 拦截器

2.1 拦截的实现原理

拦截器是可在某个方法或字段访问之前进行拦截,然后在之前或之后加入某些操作的一种程序设计思想[3]。AOP通过拦截实现关注点织入,一般要拦截一个方法可采用回调方法或动态代理。由于动态代理比较灵活,所以大多数AOP都采用动态代理实现,代理对象提供一种代理方式控制原对象的访问[4]。JDK开发包提供动态代理支持,开发者可通过实现java.lang.reflect.InvocationHandler接口提供一个执行代理器,然后通过java.lang.reflect.Proxy得到一个代理对象,通过该代理对象执行被代理类(业务逻辑)方法,在被代理类(业务逻辑)方法被调用的同时,执行处理器会被自动调用。

Struts2中的拦截器如图1所示。Struts2的Action被一个或多个拦截器所包围,所有用户请求都会被拦截器所拦截,然后交给Action处理。该调用流程由配置文件实现,当用户请求到达Struts2的 ServletDispacher时 ,Struts2会查找配置文件,并根据其配置实例化相对应的拦截器对象,然后串成一个列表(list),最后逐个调用列表中的拦截器。

图1 Struts2拦截器

2.2 拦截的意义

通过拦截形成拦截器模块,大大提高系统开发的灵活性和复用性,AOP使用代理方式,将多个拦截器和核心业务逻辑组合在一起,满足用户业务需求,这种机制克服了传统OOP设计思想所带来的各种弊端,结合OOP设计,为项目开发提供较完善的解决思路。

很多公共操作并不是所有Action都要实现的,而拦截器能将这些公共操作进行动态组合,以“插拔”方式应用到Action中[5]。开发者可根据业务需要,分离出日志记录、安全认证、文件上传、国际化等多个拦截器。拦截器的特点就是可插拔性[6],如图 2所示,拦截器1和拦截器2都是可“插拔”的,用户可以根据自己需要,增加或减少拦截器,或调整拦截器的顺序。当需要某个拦截器时,只需“插入,不需要时“拔出”即可。

图2 拦截器的插拔性

3 拦截器的应用

3.1 拦截器的定义

拦截器的“插拔“实际是通过Struts2框架的配置文件实现的,配置文件中可定义拦截器和拦截器栈,并可在Action中定义所使用的拦截器或拦截器栈(拦截器栈就是由多个拦截器组成的一个拦截器组)。在struts.xml配置文件中,拦截器的定义使用元素实现,其定义格式一般为:

3.2 拦截器的使用

定义好拦截器或拦截器栈后,可在配置文件中使用该拦截器或拦截器栈来拦截Action,指定的拦截器或拦截器栈会在Action的execute()方法执行前被执行。在配置文件的Action配置中,使用子元素配置该Action使用的拦截器或拦截器栈。

3.3 拦截器的实际应用

拦截器可应用于用户的权限认证、系统的日志记录等方面,这里以一个银行业务的日志记录为例说明拦截器的应用。银行的每一个业务操作(如转账、存款、汇款等),基本都要进行日志记录。在传统设计中,要在每一个业务操作前后进行相同记录(如经办人、交易时间、交易金额一类),不仅造成代码的臃肿,而且使得这些日志记录与业务操作耦合在一起,不利于系统的维护和升级,灵活性也较差。而采用AOP的设计思想,则可把业务操作的日志记录作为一个“横切关注点”分离出来,分离出来的日志记录模块在Struts2中应用拦截器实现,并不会影响业务模块的实现。需要时只要把该拦截器“插入”到Aicton中即可。首先建立一个日志记录拦截器,其关键代码如下:

定义好拦截器后,就可以在配置文件中使用。为了使用日志记录拦截器,需要建立一个Action。由于设置了拦截器,所以可在Action前后自动执行,很方便地在需要时加入该拦截器,而且这种方式是动态的,并且功能自由组合。

4 结论

拦截器采用一种横切式、可插拔的设计思想,提高了代码的灵活性。拦截器更为灵活的使用方法,如拦截器的方法过滤、拦截器的执行顺序、设置拦截器参数等,进一步增强了拦截器的灵活性。拦截器是实现代码复用性、扩展性的有效方法,因此会得到更广泛应用。

[1]Walls C,Breidenbach R.Spring in action[M].Beijing:Manning Publications,2007.

[2]张英捷,刘万军.Spring AOP技术在J2EE系统安全性验证中的应用研究[J].计算机科学与工程,2008,30(8):137-138.

[3]王涛涛,李晓禹,施炜利.Struts2拦截器控制页面访问权限的设计与实现[J].计算机与现代化,2009(1):32-33.

[4]曹晓利,郭顺生.AOP技术及其在J2EE中的动态代理实现[J].计算机技术与发展,2008,18(11):121-122.

[5]崔群法,王咏梅,李有军.Struts2.0从入门到精通[M].北京:电子工业出版社,2009.

[6]闫术卓,杨 强.Struts2技术详解[M].北京:电子工业出版社,2008.

猜你喜欢

拦截器插拔关注点
多动能拦截器协同制导规律的研究及仿真
英国MARSS公司推出新型反无人机拦截器
以色列“天锁”公司展出新式反无人机拦截器
冬奥关注点
寻找关注点 提高复习效率——以初中教学中“0”为关注点为例
我国有了2000米水下插拔电连接器
国产2 000 m级水下插拔电连接器问世
下半年尿素市场四大关注点
如何分析一组数据的集中和分散——数据分析的两个关注点
基于插拔力试验的汽车插座端子模具优化设计