AOP下的权限控制实现

上传人:平*** 文档编号:14302563 上传时间:2017-10-30 格式:DOC 页数:6 大小:69.16KB
返回 下载 相关 举报
AOP下的权限控制实现_第1页
第1页 / 共6页
AOP下的权限控制实现_第2页
第2页 / 共6页
AOP下的权限控制实现_第3页
第3页 / 共6页
AOP下的权限控制实现_第4页
第4页 / 共6页
AOP下的权限控制实现_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《AOP下的权限控制实现》由会员分享,可在线阅读,更多相关《AOP下的权限控制实现(6页珍藏版)》请在金锄头文库上搜索。

1、AOP 下的权限控制实现2006-07-10 05:00 作者: 陈景燕 阳国贵 出处: 计算机与信息技术 责任编辑:方舟 摘要 面向方面的编程(AOP)是一种新的编程技术,它弥补了面向对象的编程(OOP) 在跨越模块行为上的不足。AOP 引进了 Aspect,它将影响多个类的行为封装到一个可重用模块中,它允许程序员对横切关注点进行模块化,从而消除了 OOP 引起的代码混乱和分散问题,增强了系统的可维护性和代码的重用性。本文分析传统权限控制的实现方法,并研究了在 AOP 下权限控制的实现方法。关键词 AOP;横切关注点; 设计模式; 权限控制OOP 应用开发面临的问题面向对象技术很好地解决了软

2、件系统中角色划分的问题。借助于面向对象的分析、设计和实现技术,开发者可以将问题领域的“名词” 转换成软件系统中的对象,从而很自然地完成从问题到软件的转换。但是,问题领域的某些需求却偏偏不是用这样的“名词” 来描述的。比如遇到这样的问题:需要对系统中的某些方法进行权限检验,这种需要权限检验的方法散布在 40 多个类中。面对这种需求,应该怎么办呢?最直接的办法就是:创建一个起类(或接口),将权限检验的功能放在其中,并让所有需要权限检验的类继承这个起类(或接口)如果这个需求是后期提出的需要修改的地方就会分散在 40 多个文件中。这样大的修改量,无疑会增加出错的几率,并且加大系统维护的难度。人们认识到

3、,传统的程序经常表现出一些不能自然地适合单个程序模块或者几个紧密相关的程序模块的行为例如权限检验、日志记录、对上下文敏感的错误处理、性能优化以及设计模式等等、我们将这种行为称为“横切关注点( crosscuttingconcern)” ,因为它跨越了给定编程模型中的典型职责界限。如果使用过用于横切关注点的代码,您就会知道缺乏模块性所带来的问题。因为横切行为的实现是分散的,开发人员发现这种行为难以作逻辑思维、实现和更改。AOP 的基本思想AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面编程,一种新兴的编程技术。AOP 实际是 GoF 设计模式的延续,设计

4、模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP 可以说也是这种目标的一种实现。它可以解决 OOP 和过程化方法不能够很好解决的横切(crosscut)问题,如:事务、安全、日志等横切关注。当未来系统变得越来越复杂,横切关注点就成为一个大问题的时候,AOP 就可以很轻松的解决横切关注点这个问题。图 1 把模块作为一批关注点来实现通常,为满足整个企业应用某方面得需求,开发者(架构师)需要整理出系统得关注点。图 1 形象地描述了关注点,它能够从 AOP Aspect 角度看待系统。比如,持久化、日志、应用的业务逻辑通常被认为是应用需要解决的问题。因此,他们通常作为关注点看待。从整个系统角度考

5、虑,它往往是由大量的关注点构成的。我们把 AOP 看作是 OOP 的延续,而不是竞争对手。 OOP 在通常的场合下工作得很好,但在特定的领域里却有所欠缺:举例来说,如果我们必须为多个对象和方法应用相同的事务行为,我们需要将同样的代码剪切/粘贴到每一个方法里。 AOP 让我们可以把这类问题封装到方面( aspect)中,从而更好地实现模块化。AOP 定义了“切入点”(pointcut)的概念,让开发者可以从另一个角度来思考程序的结构,从而弥补了 OOP 的某些缺陷:如果需要对一组方法施加横切的行为,就应该拦截这些方法。在 J2EE 应用开发中,我们主要用到 AOP 的拦截(interceptio

6、n )能力,它为我们提供了“ 在任何对象的方法调用前/后加入自定义行为”的能力,这使得我们可以处理企业应用中的横切(crosscutting)关注点(即:同时作用于多个对象的关注点),并且仍然保持强类型(不需要改变方法签名)。权限控制的应用程序实现对于权限管理的做法,在 WEB 实现上,有以下几种: 利用 Filter,对所有进入的 URI 进行解析,并取得当时 Session 中的 User 信息,然后通过 RBAC的机制,将此链接需要的权限与用户拥有的权限进行比较,然后进行相应的处理。这种做法有很多好处:简单,容易实现,并且对系统侵入性也不强。这里 URL 就是 RBAC 中的资源了。这样

7、做的缺点是所有对数据的操作必须通过 URL 来体现,这一点在现代的程序中不太好实现。如果采用 Struts, XWork 或者Tapestry,采用同一个 URL(浏览器看来)进行处理多项任务已不是什么稀奇的事。 利用一个 BaseServlet(Servlet+Jsp 经典模式)或者 BaseAction(Struts 模式)或者 BasePage(Tapestry 模式)或者 BaseController(SpringMVC 模式) ,对所有的请求先进行过滤进行权限操作,然后再处理。稍微看一下就知道这种模式跟 Filter 并无本质不同。优缺点同上。那么,如果要实现更为细致的权限操作,精确

8、到某个方法的权限,典型的做法如下:public someFunciton() / 权限判断User user = context.getUser();if (user.canExecuteThisFunction() / do the business method/ . else throw new PermissionDeniedException();这种做法能够将权限的粒度控制到具体的业务方法,因此它的控制能力应该是强大的。可以看到,权限判断部分对于每个方法几乎是独立的。这种在具体功能前加入权限操作检验的实现方式有很多缺点: 每个功能类都需要相应的权限检验代码,将程序功能和权限检验混淆

9、在一起,存在紧密的耦合性,扩展修改难度大。 以代理模式为每个功能类实现一个相应的代理类,虽然解耦了程序功能和权限检验,但是,从某个角色的权限检验这个切面考虑,涉及具体 Proxy 类太多,扩展修改难度大。权限控制的 J2EE 容器实现在 AOP 概念没有诞生前,J2EE 规范已经提供了关于权限控制的容器实现标准,这种变迁结果如下图所示:图 2 权限控制的 J2EE 容器实现原来需要每个应用程序实现的权限 Proxy 转为整个容器的 Proxy 实现,其中 JDK1.3 以后的动态代理API 为这种转换实现提供了技术保证。非常明显,通过容器实现权限控制验证可以大大简化应用程序的设计,分离了应用系

10、统的权限关注,将权限控制变成了对 J2EE 容器服务器的配置工作。其实,容器的权限实现也是一种从一个侧面来解决问题方式,AOP 概念诞生后,权限控制实现由此也带来了两个方向的变化:J2EE 容器级别的权限实现,也就是容器自身的权限实现。J2EE 应用程序级别的权限实现。权限控制在容器级别实现似乎使得 J2EE 开发者感觉没有灵活性和可扩展性,其实象 JBoss 4.0 这样的J2EE 容器,由于引入了 AOP 概念,使得 J2EE 开发者在自己的应用系统中能够直接操纵容器的一些行为。容器和应用系统由于 AOP 引入的 Aspect 切面,变得可以成为一体了。对于 J2EE 应用系统开发者,能够

11、做到上述境界,必须的条件是对 JBoss 之类 J2EE 容器必须有足够的了解,因为这些方式并不是 J2EE 标准,有可能在移植到新的 J2EE 容器,这些知识和投入变得无用(也有可能将来 J2EE 扩展其标准)。很显然,使用 AOP 实现 J2EE 应用系统级别的权限控制,是解决上述移植风险的一个主要方法,但是带来的缺点是必须亲自从零开始做起,耗费时间不会很短。AOP 下的权限控制实现有了 AOP,新的业务方法可以这样写:public someFunciton() / do the business method/ .没有了额外的权限操作,这个业务方法看起来那么清晰自然。将对权限的操作作为一

12、个 Advice,并将 Advisor 关注到所有的业务方法(可能有某一个特定package),然后,剩下的事情就由 RBAC 以及 AOP 来完成了。通过这样的分离,纵向的一个业务方法被分割为一个更为自然的业务方法和一个关注点。这个关注点写法可能如下:public class PermissionCheckAdvice implements MethodBeforeAdvice public void before(Method arg0, Object arg1, Object arg2) throws Throwable / 权限判断if (!this.getContext().getU

13、ser().canExcute(this, arg0) throws new PermissionDeniedException();可能有个问题:如何取得 context 或者当时上下文环境的 User 呢?答案是使用 IoC(或称 Dependency Injection),将上下文环境或者 User 作为参数反向传入到逻辑方法中。当然,在传入之前,这些变量是需要初始化的。这个初始化工作可以在 SuperServlet 中进行,并且以 Session 单例的形式保存在应用程序中。下面是 Spring 配置文件的例子:beans!- Bean configuration -bean id=b

14、usinesslogicbeanclass=org.springframework.aop.framework.ProxyFactoryBeanproperty name=proxyInterfaces value IBusinessLogic /value /propertyproperty name=target ref local=beanTarget/propertyproperty name=interceptorNameslistvaluethePermissionCheckBeforeAdvisor /value /list/property/bean!- Bean Classe

15、s -bean id=beanTarget class=BusinessLogicproperty name=userYOUR USER OBJECT /property/bean!- Advisor pointcut definition for before advice -bean id=thePermissionCheckBeforeAdvisorclass=org.springframework.aop.support.RegexpMethodPointcutAdvisorproperty name=adviceref local=thePermissionCheckBeforeAd

16、vice/propertyproperty name=pattern value .*/value/property/bean!- Advice classes -bean id=thePermissionCheckBeforeAdvice class=PermissionCheckBeforeAdvice/ /beans结束语AOP 引进了 Aspect,它将影响多个类的行为封装到一个可重用模块中,它允许程序员对横切关注点进行模块化,从而消除了 OOP 引起的代码混乱和分散问题,增强了系统的可维护性和代码的重用性。利用 AOP 的拦截(interception)能力,它为我们提供了 “在任何

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号