Spring AOP属于第二代AOP。采用Java作为AOP的实现语言(AOL),采用动态代理机制和字节码生成技术实现。
代理设计模式
- ISubject 对被访问者或者被访问资源的抽象,某些场景下不使用类似的统一抽象接口也可以
- SubjectImpl 具体实现类
- SubjectProxy 代理实现类
- Client 代表访问者的抽象角色
代理不只局限于请求的转发,更多时候是对请求添加更多访问限制或简化使用
Spring AOP本质上就是采用这种代理机制实现的
Java 平台上的AOP实现机制
- 动态代理
通过JDK 1.3引入的动态代理机制,为相应的接口动态生成对应的代理对象,SPring AOP默认情况下采用这种机制。但动态代理只能对实现了相应Interface的类使用。 - 动态字节码增强
使用ASM或者CGLIB等Java工具库,在程序运行期间,动态构建字节码的class文件,只要满足Java虚拟机加载的class规范就行。无需接口,唯一限制就是无法对final 方法进行覆写。 - Java代码生成
比较古老,已退休 - 自定义类加载器
所有的Java程序的clas都要通过相应的类加载器加载到Java虚拟机之后才能运行。功能比之前几种方式强大,但加重类加载器本身的负担 - AOL扩展
最强大,最难掌握。
Spring AOP
AOP基本概念实现
- Joinpoint
仅支持方法级别的Joinpoint(Metho Execution),可以满足80%的开发需求了。 - Pointcut
Advice
Aspect
Advisor代表Spring中的Aspect,但是,与正常的Aspect不两只,Advisor通常只持有一个Pointcut和一个Advice。而理论上,Aspect定义可以有多个Pointcut和Advice
织入 ProxyFactory
俗话说得好,“万事俱务,只欠东风”,各个模块已经实现了,最后一步就是拼装了。
要进行织入,AspectJ采用ajc编译器;JBoss AOP使用自定义的ClassLoader,而Spring AOP使用类org.springframework.aop.framework.ProxyFactory作为织入器。
几种Spring AOP
- Spring AOP 1.x 基于接口定义的的Advice声明方式:各种类型的Adivce定义需要实现特定的接口,Advice的管理可以通过IoC容器或者直接编程进行。
- @AspectJ 2.0之后新增加,只需要以POJO形式声明相应的Aspect和Advice,然后通过相应的注解标注一下即可。各种信息的管理统一到一个位置,并且由于IDE的重构支持,AOP的管理更加方便高效。
- 基于Schema的AOP。融合第一代和第二代。各种信息转移到XSD形式的容器配置文件中。
应该依照当前应用环境、各种工具支持、整体团队能力等不同情况来权衡利弊。