Spring AOP采用Java作为AOP的实现语言(AOL),学习曲线平滑,Spring AOP对AspectJ也提供了很好的集成与支持。最为第二代的AOP,采用动态代理机制和字节码生产技术实现,在运行期间为目标对象生成一个代理对象,将横切逻辑织入到这个代理对象中,系统使用织入了横切逻辑的代理对象。
在深入剖析Spring AOP之前,我们有必要先了解一下代理模式,代理模式可以简单地分成:静态代理模式和动态代理模式。静态代理模式作为设计模式中比较简单的一种模式,我们不做过多的分析;动态代理模式是JDK1.3之后引入的,使用该机制,我们可以为指定的接口在系统运行期间动态地生成代理对象。动态代理机制与静态代理的区别就在于把原先的一个代理类划分成一个Proxy类再加一个InvocationHandler接口,Proxy负责生产相应的动态代理实例,InvocationHandler负责拦截相应的方法调用。InvocationHandler就是实现横切逻辑的地方,作用类似于Adcice。动态代理模式的缺陷是只对实现了Interface的类有效。Spring AOP默认使用动态代理机制,无效时采用名为CGLIB的动态字节码生产类库,为目标对象生成动态的代理对象实例。
我们知道,基于面向对象语言的继承性,子类对象可以作为父类来使用。但是,使用继承的方式具有和静态代理一样的问题,需要为每个不同类型的目标对象都单独创建相应的扩展子类,借助CGLIB这样的动态字节库,在系统运行期间动态地为目标生成相应的扩展子类。使用CGLIB的唯一限制是无法对final类和final方法进行复写。
Spring AOP只支持方法执行类型的Joinpoint,这样做是为了付出20%的努力达到80%的效果。Spring AOP中以接口定义Pointcut作为其AOP框架中所有Pointcut的最顶层抽象,其中定义了两个方法用来帮助扑捉相应的Jointpoint。
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
Pointcut TRUE = TruePointcut.INSTANCE;
}
对于其中的ClassFilter和MethodMatcher,我们看一下他们的具体接口定义:
public interface ClassFilter {
boolean matches(Class clazz);
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
public interface MethodMatcher {
boolean matches(Method method, Class targetClass);
boolean isRuntime();
boolean matches(Method method, Class targetClass, Object[] args);
MethodMather TRUE = TrueMethodMatcher.INSTANCE;
}
简单来说,ClassFilter的存在是为了进行类的过滤,粒度比较粗,MethodMatcher是做方法的过滤,而且为了提高性能重载了matches方法,分为静态过滤和动态过滤,它们之间的分界线是isRuntime方法。
在Spring AOP中,已经为我们提供了好几个Pointcut实现,满足我们一般的需求。我们来简单分析一下各种实现的特点。
+ NameMatchMethodPointcut 属于静态匹配的子类,只考虑方法名,不考虑参数
+ AbstractRegexMethodPointcut 利用正则表达式进行匹配,可以匹配整个方法签名
+ AnnotationMatchingPointcut 利用注解来进行匹配,分为类级别和方法级别
+ ComposablePointcut 可进行逻辑运行的Pointcut实现
+ ControlFlowPointcut 匹配程序的调用流程
除了以上介绍的各种Pointcut,如果有自己的需求,我们也可以实现自己的Pointcut。
Spring AOP加入了开源组织,Spring中Advice的实现全部遵循AOP Alliance规定的接口。我们知道Advice是承载横切逻辑的地方,根据自身实例能否被目标对象类的所有实例所共享,划分成per-class类型与per-instance类型。只有Introduction类型的Advice属于per-instance类型,不能共享。

下面,我们开始简单地介绍各种Advice:
+ Before Advice 可通过抛出异常来打断方法流程
+ ThrowsAdvice 可用来进行异常情况的监控
+ AfterReturningAdvice 可访问当前Joinpoint的返回值、方法、方法参数和目标对象,但是不能更改返回值。
+ Around Advice 就是MethodInterceptor接口,功能非常强大。
以上介绍的都是pre-class类型的Advice。下面我们开始介绍Introduction,该Advice可以在不改动目标类定义的情况下,为目标类添加新的属性以及行为。根据是否可以在运行时动态配置和判断当前Introduction可应用的目标接口类型,划分为静态分支和动态分支。
在知道Pointcut和Advice之后,我们再看把他们集合到一起的Aspect。AOP中Aspect可以包含多个Pointcut和多个Advice,而我们Spring AOP中的对等实体Advisor是一种特殊的Aspect,通常只持有一个Pointcut和一个Advice。关于Advisor的体系结构,我们可以简单地分成两个分支:

针对其中PointcutAdvisor,我们来看一下其常见的子类:
+ DefaultPointcutAdvisor 除了Intorduction以外的Advice都可以
+ NamematchMethodPointcutAdvisor 限制只能使用NameMatchMethodPointcut
+ RegexMethodPointcutAdvisor 限制只能使用AbstractRegexMethodPointcut
+ DefalutBeanfactoryPointcutAdvisor 绑定到了BeanFactory,使用较少
对于IntroductionAdvisor,其只能用于类级别的拦截,只能够使用Introduction型的Advice,其常见子类只有一个:
+ DefaultIntroductionAdvisor
为了解决同一个Joinpoint应用的多个Advice执行的先后顺序问题,我们可以指定它们的Order值,默认情况下,先声明的Adice优先级更高,更好的解决方案是直接在Advisor上指定它们的order值,值越小,优先级越高。
在Pointcut、Advice、Aspect等各种元素都已准备好的情况下,我们还需要准备的就是织入器了。AspectJ采用ajc编辑器作为它的织入器,JBoss AOP使用自定义的ClassLoader作织入器,Spring AOP使用类ProxyFactory作为织入器。注意,ProxyFactory并不是Spring中的唯一织入器,而是最常见织入器。使用织入器,我们只需要为其提供两样最基本的东西。
+ 将要织入的目标对象
+ 要应用的Aspect,也就是Advisor。
我们知道Spring内部使用了动态代理和CGLIB两种机制,所以ProxyFactory内部会根据一定的算法自动在这两个机制之间切换。注意:对于Advice和Advisor,Introduction的部分是不能与其他Advice和Advisor混用的。   我们知道,Spring中关于AOP的实现是通过ProxyFactory类来实现的。现在我们来看看ProxyFactory的具体细节,首先看它的根部AopProxy接口。
public interface AopProxy {
Object getProxy();
Object getProxy(ClassLoader classLoader);
}
Spring AOP框架使用AopProxy对不同代理实现机制进行抽象。其中AopProxy的相关结构图如下所示:

可以看到,不同的AopProxy实现的实例化过程采用了抽象工厂模式。
随着JDK和Spring的升级,现在Spring AOP的使用方式已经包含有三种形式了,他们分别是基于接口和XSD的第一代AOP、基于注解的第二代AOP、基于Schema的第二代AOP,虽然配置方式多了,但他们的效果是相同的,可以根据自己的实际情况进行选择。
下面我们来讲讲AOP的应用场景和案例:
+ 异常处理 主要针对unchecked exception
+ 安全检查 Spring security
+ 缓存
AOP虽然很好地解决了等多系统需求的问题,下面我们就来看看在使用AOP的过程中应该注意的一些问题。
+ 公开当前调用的代理对象的探讨

AOP学习笔记二的更多相关文章

  1. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  2. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  3. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  4. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  5. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  6. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  7. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  8. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  9. Learning ROS for Robotics Programming Second Edition学习笔记(二) indigo tools

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

随机推荐

  1. MySQL备份说明

    第一次发布博客,发现目录居然不会生成,后续慢慢熟悉博客园的设置.回正文--- 1 使用规范 1.1 实例级备份恢复 使用innobackupex,在业务空闲期执行,考虑到IO影响及 FLUSH TAB ...

  2. Ionic2中集成第三方控件Sweetalert

    Ionic2混合开发,入坑系列:Ionic2中集成第三方控件Sweetalert 注:Sweetalert2已经可以直接从npm中下载安装 npm install --save sweetalert2 ...

  3. 概念 : 过程 : 前台login

    为了解决自动登入.访问权限机制.登入权限而诞生了这过程,过程需要概念来维护记忆. 通过singlePageAutoLoginLocalStorage, UIStateLocalStorage, Use ...

  4. Zookeeper + Kafka 集群搭建

    第一步:准备 1. 操作系统 CentOS-7-x86_64-Everything-1511 2. 安装包 kafka_2.12-0.10.2.0.tgz zookeeper-3.4.9.tar.gz ...

  5. 问题 : lang.NoClassDefFoundError: org/springframework/core/annotation/AnnotatedElementUtils,的解决方法

    今天在做junit 测试的时候  出现了一个问题,花了一段时间 才解决. java.lang.NoClassDefFoundError: org/springframework/core/annota ...

  6. 数据库基础——(SQLserver)约束

                                                              数据库定义:一些存储在硬盘上的数据文件 内存:计算机临时存储的一些数据 .net - ...

  7. tp框架 :操作数据库

    操作数据库,进行增删改数据 一.对数据表添加数据(方法:add()) (1)上一篇已经讲过链接数据库了,继续进行对数据库的操作,还是用控制器文件中的HomeController.class文件 看下数 ...

  8. 1113: [Poi2008]海报PLA

    1113: [Poi2008]海报PLA Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 765  Solved: 466[Submit][Status ...

  9. 1687: [Usaco2005 Open]Navigating the City 城市交通

    1687: [Usaco2005 Open]Navigating the City 城市交通 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 94  Sol ...

  10. docker X509 证书错误的终极解决办法

    最近在做Docker相关的东西,发现只要一pull镜像,就出现如下的ERROR x509: certificate signed by unknown authority. 调查后发现,是公司IT把h ...