天天看点

AOP 面向切面编程

AOP 概述

面向切面编程(AOP)和面向对象编程(OOP)类似,也是一种编程模式。Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的。

AOP 的全称是“Aspect Oriented Programming”,即面向切面编程,它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。

AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。

目前最流行的 AOP 框架有两个,分别为 Spring AOP 和 AspectJ。

Spring AOP 使用纯 Java 实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类植入增强的代码。

AspectJ 是一个基于 Java 语言的 AOP 框架,从 Spring 2.0 开始,Spring AOP 引入了对 AspectJ 的支持。AspectJ 扩展了 Java 语言,提供了一个专门的编译器,在编译时提供横向代码的植入。

为了更好地理解 AOP,就需要对 AOP 的相关术语有一些了解,这些专业术语主要包含 Joinpoint、Pointcut、Advice、Target、Weaving、Proxy 和 Aspect,它们的含义如下表所示。

AOP 面向切面编程

JDK 动态代理

当 Spring 没有手动开启 Cglib 动态代理,即:

<aop:aspectj-autoproxy proxy-target-class="true"/>

@EnableAspectJAutoProxy(proxyTargetClass = true)

,默认使用的就是Jdk动态代理。

动态代理的应用范围很广,例如:日志、事务管理、缓存等。需要注意的是,Jdk动态代理相比起cglib动态代理,Jdk动态代理的对象必须实现接口,否则将报错。

CGLIB 动态代理

通过教程的学习可以知道,JDK 动态代理使用起来非常简单,但是它也有一定的局限性,这是因为 JDK 动态代理必须要实现一个或多个接口,如果不希望实现接口,则可以使用 CGLIB 代理。

CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它被许多 AOP 框架所使用,其底层是通过使用一个小而快的字节码处理框架 ASM(Java 字节码操控框架)转换字节码并生成新的类。

Spring 通知类型和创建 AOP 代理

Spring 通知类型

通知(Advice)其实就是对目标切入点进行增强的内容,Spring AOP 为通知(Advice)提供了

org.aopalliance.aop.Advice

接口。

AOP 面向切面编程

声明式 Spring AOP

Spring 使用

org.springframework.aop.framework.ProxyFactoryBean

创建一个 AOP 代理,这个类对应的切入点和通知提供了完整的控制能力,并可以生成指定的内容。

AOP 面向切面编程

使用 AspectJ 开发 AOP

AspectJ 是一个基于 Java 语言的 AOP 框架,它扩展了 Java 语言。Spring 2.0 以后,新增了对 AspectJ 方式的支持,新版本的 Spring 框架,建议使用 AspectJ 方式开发 AOP。

基于 XML 的声明式

基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面、切入点及声明通知,而所有的切面和通知都必须定义在

<aop:config>

元素中。

基于 Annotation 的声明式

在 Spring 中,尽管使用 XML 配置文件可以实现 AOP 开发,但是如果所有的相关的配置都集中在配置文件中,势必会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。

为此,AspectJ 框架为 AOP 开发提供了另一种开发方式——基于 Annotation 的声明式。AspectJ 允许使用注解定义切面、切入点和增强处理,而 Spring 框架则可以识别并根据这些注解生成 AOP 代理。

AOP 面向切面编程