精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-10
3.3. AOP应用案例(AOP Use cases)在结束本章有关Spring AOP的话题之前,我觉得有必要从最普通的层面对适合使用AOP解决的问题场景做一简单的介绍,您愿意称其为“AOP的最佳实践 ”那也未尝不可! 或许你已经在使用类似于AOP的方式对应用程序中的某些异常进行统一的处理,也或许你已经在使用AOP的方式进行异常处理,但你可能并没有意料到这实际上对应一个很有趣的概念,叫做“Fault Barrier ”, 在接触这个名词之前,笔者实际上已经将这个概念所阐述的理念应用于工作中,直到看到dev2dev上一篇《Effective Java Exception》,我才知道,原来这种异常的处理方式,还对应一个这么“有趣的 ”术语。 不过,在进入“Fault Barrier ”之前,我们有必要先来回顾一下Java中的异常处理相关内容... 关于异常的处理是一个很大的话题,所以,限于篇幅,我们不可能事无巨细的对异常处理的方方面面都提及,只是对Java中通常的异常类型和处理方式做一简单回顾,以便引出Fault Barrier的概念。 Java不是最早也不是唯一使用异常机制的语言,不过,Java却在引入“Checked Exception ”的基础上为其自身的异常处理添加了少许的新意。我们先来看一下Java中的异常层次体系大体上是一种什么样的结构,如下图: 在该图中,我们将java中的异常类型分为两类:
各位大师级人物对“checked exception ”和“unchecked exception ”的论战我们暂且放在一边, 不过,对于二者具体的应用场景我们有必要了解一下,毕竟基本原则还是有的,至于用好用不好那就由不得人了:
在《Effective Java Exception》中,作者将“unchecked exception ”对应的情况称之为“Fault ”,而将“checked exception ”对应的情况称之为“Contingency ”. 而我们的“Fault Barrier ”要处理的,就是对应Fault的情况。 对于“checked exception ”来说,不同的类型可以有不同的处理方式,这完全是由系统逻辑来决定的,调用方可以根据不同的类型,有针对性的对“checked exception ”进行处理; 反过来,对于“unchecked exception ”来说,不同的类型则是没有太多必要的,因为不管你的应用程序抛出何种类型的“unchecked exception ”, 最终都是需要人来进行干预,只要“unchecked exception ”能够提供足够的信息,相应人员就可以进行处理,完全就是无差别对待。 当系统中多个地方都可能抛出“unchecked exception ”的时候,在此之前,我们可能会在每一个调用的最顶层分别添加异常处理逻辑对其进行处理,而就像我们所说的那样, 对于“unchecked exception ”来说,实际上可以做的事情很少,通常就是记录日志,通知相应人员,所以,这些相同的逻辑实现实际上应该归并于一处进行处理,而不是让他们散落到系统的各处,也就是说, 对于系统中的Fault来说,它实际上就是一种横切关注点(Cross-cutting concern)。 鉴于此,我们完全可以实现一个对应Fault处理的Aspect,让其对系统中的所有可能的Fault情况进行统一的处理,那么,这个专职于处理Fault的Aspect,我们就可以称之为“Fault Barrier ”。 实际上,我们从讲解SpringAOP的ThrowsAdvice开始,就提供了一个“Fault Barrier ”的实现实例,在该实例中,我们通过email方式将系统中的Fault情况,也就是以“unchecked exception ”形式给出的信息转发给相关人员,并记录到日志。 当然,如果可能,你还可以加入更多的处理,比如分析“unchecked exception ”信息,为相关人员提供更加友好的系统信息等等。 Note任何的概念都会有特例,对于异常来说也是如此,比如“unchecked exception ”也可以被相应的方法声明并被调用方捕获,不过,前面也说了,篇幅有限,无法完全囊括所有内容, 对于特殊的情况,如果后继内容有所牵扯,我们会给予相应解释。 如果你已经Java开发web应用程序多年,那么,你一定不会对使用Filter为系统的资源访问添加控制而感到陌生吧? javax.servlet.Filter可以算是servlet规范为我们提供的一种AOP支持,通过它,你可以为基于servlet的web应用添加相应的资源访问控制(当然,还可以做很多其他事情)。 不过,基于Filter的web应用的资源访问控制仅仅是特定领域的安全检查需求,实际上,通过AOP,你可以为任何类型的应用添加相应的安全支持。 在介绍AOP概念的时候我们就曾经提到过,安全检查属于系统的一种横切关注点,按照原先的方法进行系统开发,势必让这些安全检查逻辑散落系统各处, 所以,对付它的最好办法就是用AOP。在将系统中可能需要安全检查的点排查清楚之后,我们就可以为这些点织入安全检查的逻辑了。 要为系统中某个点添加安全支持,最简单的办法就是提供一个Interceptor,对所有访问该点的调用进行拦截。所以,对于基本的一个安全检查的Aspect实现来说,基本类似于: @Aspect public class SecurityAspect { @Around("...") public Object doCheck(ProceedingJoinPoint pjp) throws Throwable { if(isIllegalRequest(pjp)) { throw new SecurityCheckingException("necessary information"); } return pjp.proceed(); } }不过,既然我们崇尚“不重新发明轮子 ”, 在动手之前,有必要google一下是否有现成的,也好免去人力物力的浪费啊。 实际上,作为基于Spring平台的一套安全框架,Acegi framework现在可以说在企业级应用的安全领域声名远扬了。 它在Spring基础之上,提供了完备的系统认证,授权,访问控制等安全检查功能。Acegi Framework最初是独立于Spring开发的,现在已经并入Spring portfolio,更名为Spring Security, 你可以在http://www.acegisecurity.org/获得有关Acegi的更多信息。 AOP应用的另一个主要场景在于为系统透明的添加缓存支持。缓存可以在很大程度上提供系统的性能,但它不属于业务需求, 而是系统需求,在现有方法论的基础之上要为系统添加缓存支持,就会因为系统中缓存需求的广泛分布,造成实现上的代码散落。 为了避免需要添加的缓存的实现逻辑污染业务逻辑的实现,我们可以让缓存的实现独立于业务对象的实现之外,将系统中的缓存需求通过AOP的Aspect进行封装, 只有当系统中某个点确切需要缓存支持的情况下,才为其织入。 使用AOP为系统添加缓存其实很简单,比如: @Aspect public class CachingAspect { private static Map cache = new LRUMap(5); @Around("...") public Object doCache(ProceedingJoinPoint pjp,Object key) throws Throwable { if(cache.containsKey(key)) { return cache.get(key); } else { Object retValue = pjp.proceed(); cache.put(key, retValue); return retValue; } } }我想,在没有使用AOP之前,要为系统某个地方加入缓存的话,你也是以差不多的逻辑实现的。 不过,现在我们实际上不需要这么做了:
Note更多AOP的应用场景和最佳实践还需要您自己去挖掘,去探索... 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-11
最后修改:2009-06-11
一本好书,严重支持
![]() |
|
返回顶楼 | |
发表时间:2009-06-16
堆系统理解如此之深。。没有几年的功力和对Java项目的实践操作是不可能有如此大作的。
|
|
返回顶楼 | |
浏览 2911 次