第11章 AOP应用案例

本章内容

  • 异常处理
  • 安全检查
  • 缓存

在结束有关SpringAOP的话题之前,有必要从最一般的层面上对适合使用AOP的场景做一个简单的介绍。如果称这些场景为AOP的最佳实践,其实未尝不可!

异常处理

或许你已经在使用AOP的方式进行异常处理,但是可能并不知道这实际上对应着一一个很有趣的术语,叫做Fault Barrier。同样地,在接触这个术语之前,我实际上已经将这个概念所阐述的理念应用于工作中,直到看到dev2dev网站上的一篇文章“Effective Java Exception",才知道原来这种异常的处理方式还对应这么一个有趣的术语。

不过,在讲述Fault Barrier之前,我们有必要先来回顾一下Java中异常处理的相关内容。

Java异常处理

异常处理是个很大的话题,限于篇幅,我们不可能详细讲述异常处理的方方面面。

下面只是简单地回顾一下Java中的异常类型和对应的处理方式,以便引出Fault Barrier的概念。

Java不是最早也不是唯一使用异常机制的语言。不过,Java却在引入CheckedException的基础上为其自身的异常处理添加了少许的新意。我们先来看一下Java中的异常层次体系大体上是一种什么样的结构,如图11-1所示。

在图11-1中,我们将Java中的异常类型分为如下两类。

  • 通常将java.lang.Errorjava.lang.RuntimeException及其子类称之为unchecked exception。之所以如此称呼,是因为编译器不会对这些类型的异常进行编译期检查。因为java.lang.Error我们通常关心不着,所以,狭义上将java.lang.RuntimeException及其子类暂且称为unchecked exception也是可以的。
  • java.lang.Exception及其子类,但除去java.lang.RuntimeException分支,统称为checked exception。一旦在程序的方法定义中声明了将会抛出“checked exception",调用程序就必须对这些异常进行处理,而且编译器会在编译期间对这些异常类型进行检查

各位大师级人物对checked exception和unchecked exception的论战暂且放在一边,我们主要讲述一下二者具体的应用场景。

  • unchecked exception通常对应系统中的严重异常情况,这些情况应用程序一般无法恢复,比如数据库挂掉、网线连接中断、服务器崩溃等。所以,unchecked exception所提供的信息一般不是为应用程序准备的,而是为人准备的,确切地说,是为了能够让系统维护人员能够根据所提供的信息来判定到底哪里出了问题,以便人工干预。

  • checked exception引入Java后,一直是备受争议。不过,我觉得这与概念本身没有任何关系,是否被应用于合适的场合是由人来决定的,而不是概念本身。checked exception通常用于表明系统中的某些罕见的非正常状态。对于一个业务方法来说,使用错误号(ErrorCode)的时代是通过返回-1之类数字表明一些非正常状态,现在可以通过抛出不同类型的checked exception来表明这些非正常状态,并要求调用方对这些非正常状态进行处理,而编译器对checked exception的检查可以进一步加强这种关系。通常checked exception是可恢复的,也是意料之中的,它所提供的信息是面向应用程序的,应用程序可以根据系统逻辑对不同的checked exception类型进行有针对性的处理

在技术文章"Effective Java Exception"中,作者将unchecked exception对应的情况称之为Fault。而将checked exception对应的情况称之为Contingency(意外事故)。

而FaultBarrier要处理的,就是对应Fault的情况,即unchecked exception。

FaultBarrier

对于checked exception来说,不同的类型可以有不同的处理方式,这完全是由系统逻辑来决定的,调用方可以根据不同的类型,有针对性地对checked exception进行处理。反过来,对于unchecked exception来说,不同的类型则是没有太多必要的,因为不管你的应用程序抛出何种类型的unchecked exception,最终都是需要人来进行干预,只要unchecked exception能够提供足够的信息,相应人员就可以进行处理,几乎就是无差别对待。

当系统中多个地方都可能抛出unchecked exception的时候,在引入Fault Barrier概念之前,我们可能会在每个调用的最项层,分别添加异常处理逻辑对其进行处理。而就像前面所说的那样,unchecked exception实际上可以做的事情很少,通常就是记录日志、通知相应人员。所以,这些相同的逻辑实现可以归并于一处进行处理,而不是让它们散落到系统的各处,也就是说,对于系统中的Fault来说,它实际上就是一种横切关注点(cross cutting concern)。

鉴于此,我们完全可以实现一个对应Fault处理的Aspect,让其对系统中的所有可能的Fault情况进行统一的处理。这个专职于处理Fault的Aspect,我们就称之为Fault Barrier。实际上,我们从讲解SpringAOP的ThrowsAdvice开始,就提供了一个FaultBarrier的实现实例。在该实例中,我们通过电子邮件的方式将系统中的Fault情况,也就是以unchecked exception形式给出的信息转发给相关人员,并记录到日志。当然,如果可能,你还可以加入更多的处理,比如分析unchecked exception信息、为相关人员提供更加友好的系统信息等。

安全检查

如果你已经使用Java开发Web应用程序多年,那么一定不会对Filter感到陌生吧?javax.servlet.Filter是Servlet规范为我们提供的一种AOP支持,通过它,我们可以为基于Servlet的Web应用添加相应的资源访问控制(当然,还可以做很多其他事情)。

不过,基于Filter的Web应用的资源访问控制,仅仅是特定领域的安全检查需求。实际上,通过AOP,我们可以为任何类型的应用添加相应的安全支持。

在介绍AOP概念的时候就曾经提到过,安全检查属于系统的一种横切关注点,按照原先的方法进行系统开发,势必让这些安全检查逻辑散落系统各处,所以,对付它的最好办法就是用AOP。在将系统中可能需要安全检查的点排查清楚之后,我们就可以为这些点织入安全检查的逻辑了。

要为系统中某个点添加安全支持,最简单的办法就是提供一个拦截器,对所有访问该点的调用进行拦截。所以,对于基本的安全检查的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框架(也就是最新的Spring Security)已经可以说在企业级应用的安全领域声名远扬了。它在Spring基础上,提供了完备的系统认证、授权、访问控制等安全检查功能。Acegi框架最初是独立于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之前,要为系统某个地方加入缓存的话,恐怕也是以差不多的逻辑实现的。不过,现在不需要这么做了,原因如下

  • 现在已经有许多现成的Caching产品实现,如EhCache、JBossCache等。
  • Spring Modules项目提供了对现有Caching产品的集成,这样就可以通过外部声明的方式为系统中的Joinpoint添加Caching支持。

本章小结

本章给出了几种常见的AOP应用场景(或最佳实践),以帮助读者扩展AOP的应用思路。但实际上,AOP的应用场景可以很广,而不只局限于本章罗列的这几种情况。关于AOP的更多应用场景和最佳实践,需要读者在实际开发中自己去挖据,去探索。

第11章 AOP应用案例相关推荐

  1. 《MATLAB 神经网络43个案例分析》:第11章 连续Hopfield神经网络的优化——旅行商问题优化计算

    <MATLAB 神经网络43个案例分析>:第11章 连续Hopfield神经网络的优化--旅行商问题优化计算 1. 前言 2. MATLAB 仿真示例 3. 小结 1. 前言 <MA ...

  2. 学籍管理系统 c语言流程图,程序设计基础 ——C语言第10章 综合应用案例——学生学籍管理系统...

    程序设计基础 第 10章 综合应用 案例 -学生学籍 管理系统 1 详细设计 需求分析 总体设计 第 10章 综合应用 案例 -学生学籍管理系统 编码实现 运行结果 2 设计一个利用 文件 处理方式, ...

  3. 0与1c语言编译,C语言程序设计(07776-1)第11章编译预处理课案.ppt

    C语言程序设计(07776-1)第11章编译预处理课案.ppt 第11章 编译预处理 主要内容 宏定义 文件包含 条件编译 程序案例 小结 习题 11-1 宏定义 不带参数的宏定义 带参数的宏定义 终 ...

  4. Spring - Java/J2EE Application Framework 应用框架 第 11 章 使用ORM工具进行数据访问

    第 11 章 使用ORM工具进行数据访问 11.1. 简介 Spring在资源管理,DAO实现支持以及实物策略等方面提供了与Hibernate, JDO和iBATIS SQL映射的集成. 对Hiber ...

  5. 弟子规python编程游戏_《Python游戏趣味编程》 第11章 消灭星星

    知乎视频​www.zhihu.com 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了​zhuanlan.zhihu.com 消灭星星是一款非常容易上瘾的消除类游戏,只需 ...

  6. 第 11 章 树结构实际应用

    第 11 章 树结构实际应用 1.堆排序 1.1.堆排序基本介绍 堆排序是利用堆这种数据结构而设计的一种排序算法, 堆排序是一种选择排序, 它的最坏, 最好, 平均时间复杂度均为 O(nlogn), ...

  7. 2022版Maven教程 - 第六章 单一架构案例

    2022版Maven教程 - 第六章 单一架构案例 一.创建工程,引入依赖 1.架构 ①架构的概念 ②单一架构 2.创建工程 3.引入依赖 ①搜索依赖信息的网站 [1]到哪儿找? [2]怎么选择? ② ...

  8. 第 11 章 一 执行引擎概述、解释器、JIT编译器-热点代码优化

    第 11 章 执行引擎 Java到底是编译型语言还是解释型语言? 编译程序基本原理 首先Java通过源码编译器 Javac命令将源代码编译为字节码文件(.class文件), 字节码这种二进制流的文件不 ...

  9. Python金融大数据分析——第11章 统计学(1)正态性检验 笔记

    第11章 统计学 11.1 正态性检验 11.1.1 基准案例 11.1.2 现实世界的数据 第11章 统计学 11.1 正态性检验 可以说 , 正态分布是金融学中最重要的分布 , 也是金融理论的主要 ...

最新文章

  1. 强化学习(五)---基于模型的强化学习实战
  2. MySQL的insert into select 引发锁表
  3. 浅析THINKPHP的addAll支持的最大数据量
  4. C#模拟最简单的交通信号灯
  5. 第三次学JAVA再学不好就吃翔(part117)--单例设计模式
  6. python下载微信公众号文章_python如何导出微信公众号文章
  7. Oracle行列转换小结
  8. 关于fsockopen pfsockopen函数被禁用的解决方法
  9. Python使用管道实现进程间数据传递
  10. 开课吧Java课堂:StringBuffer全解,非常详细
  11. SSAS中出现“对象引用未被设置到对象实例”的解决记录
  12. 全国青少年软件编程等级考试标准(正式级)
  13. 图论及其应用(基础知识)(1)(数学建模基础速成)
  14. 数据分析必备算法(算数平均值,加权平均值,最值,中位数,标准差,时间数据处理 ,数组的轴向汇总, 移动均线 ,卷积(简单概念))
  15. 使用React Native源码编译Android项目
  16. 高德地图全解析--定位篇
  17. 机器学习开源框架系列:Torch:1:简介与安装
  18. 你有哪些“相见恨晚”的UE4学习资料?
  19. 百度地图 开启 绘制 功能(画圆)
  20. 华为magic ui就是鸿蒙系统,Magic UI系统是什么?Magic UI和EMUI的区别

热门文章

  1. 用zabbix监测snmptrap的主动告警功能
  2. 用友OA漏洞学习——test.jsp SQL注入漏洞
  3. 海康28181摄像头接入的注意点
  4. Composer安装Laravel最简单、详细图解
  5. SQL server-数据库的查询(高级)
  6. 解决log4j.dtd 和系统中所有dtd文件都有红XX的问题
  7. Python与Excel——Xlwings基础操作
  8. camera驱动开机加载流程
  9. 佳能打印机浏览不到计算机,电脑为什么不识别佳能打印?
  10. CSS 画一个圆的背景 样式