面向切面编程(Aspect-Oriented Programming,简称AOP)作为面向对象编程(OOP)的重要补充,主要致力于处理那些具有横切性质的系统级服务,例如日志记录、事务控制、安全验证、缓存机制以及对象池管理等。
AOP实现的核心在于AOP框架自动生成的AOP代理,这些代理可以分为静态代理和动态代理两种类型。静态代理指的是利用AOP框架提供的指令在编译阶段生成AOP代理类,因此也被称为编译时增强;而动态代理则是在运行时通过JDK动态代理或CGLIB等技术于内存中动态创建AOP代理类,因此也被称为运行时增强。
作为一种编程范式,面向切面编程(AOP)旨在通过允许横切关注点的分离,从而提升模块化水平。AOP提供切面来将跨越对象关注点进行模块化处理。
AOP的主要目标是基于已编写的代码进行特定的包装,例如在方法执行前、执行后或执行过程中出现异常时进行拦截处理或增强处理。
Pointcut:指的是基于正则表达式的表达式,虽然表述略显复杂,但本质上是一个表达式,其语法基于正则表达式。通常一个pointcut会选择程序中某些特定的执行点,或者说是程序执行点的集合。
JoinPoint:指的是通过pointcut选取出的集合中的具体一个执行点,我们称之为JoinPoint。
Advice:指的是在选取出的JoinPoint上要执行的操作或逻辑。关于其五种类型,这里不再赘述,建议读者自行补充基础知识。
Aspect:指的是关注点的模块化。这种关注点可能会横切多个对象和模块,例如事务管理就是横切关注点的典型例子。它是一个抽象概念,从软件角度来看,是指在应用程序不同模块中的某个领域或方面。Aspect由pointcut和advice共同组成。
Weaving:指的是将切面应用到目标对象来创建新的advised对象的过程。
AspectJ是一个易于使用且功能强大的AOP框架。
AspectJ的完整名称是Eclipse AspectJ,其官网地址为:www.eclipse.org/aspectj/,目前……
引用官网描述:
- a seamless aspect-oriented extension to the Javatm programming language(一种基于Java平台的面向切面编程的语言)
- Java platform compatible(兼容Java平台,可以无缝扩展)
- easy to learn and use(易于学习和使用)
AspectJ可以独立使用,也可以整合到其他框架中。
单独使用AspectJ时需要使用专门的编译器ajc。

Java的编译器是javac,而AspectJ的编译器是ajc,其中aj是首字母缩写,c即compiler。
相信作为Java开发者,我们都很熟悉Spring这个框架,在Spring框架中有一个主要功能就是AOP,提到AOP就往往会想到AspectJ,下面我对AspectJ和Spring AOP作一个简单的比较:
1、基于动态代理来实现,默认如果使用接口的,则使用JDK提供的动态代理实现,如果是方法则使用CGLIB实现
2、Spring AOP需要依赖IOC容器来管理,并且只能作用于Spring容器,使用纯Java代码实现
3、在性能上,由于Spring AOP是基于动态代理来实现的,在容器启动时需要生成代理实例,在方法调用上也会增加栈的深度,使得Spring AOP的性能不如AspectJ的那么好
- AspectJ来自于Eclipse基金会
- AspectJ属于静态织入,通过修改代码来实现,有如下几个织入的时机:
1、编译期织入(Compile-time weaving): 如类 A 使用 AspectJ 添加了一个属性,类 B 引用了它,这个场景就需要编译期的时候就进行织入,否则没法编译类 B。
2、编译后织入(Post-compile weaving): 也就是已经生成了 .class 文件,或已经打成 jar 包了,这种情况我们需要增强处理的话,就要用到编译后织入。
3、类加载后织入(Load-time weaving): 指的是在加载类的时候进行织入,要实现这个时期的织入,有几种常见的方法。1、自定义类加载器来干这个,这个应该是最容易想到的办法,在被织入类加载到 JVM 前去对它进行加载,这样就可以在加载的时候定义行为了。2、在 JVM 启动的时候指定 AspectJ 提供的 agent:-javaagent:xxx/xxx/aspectjweaver.jar。
- AspectJ可以做Spring AOP干不了的事情,它是AOP编程的完全解决方案,Spring AOP则致力于解决企业级开发中最普遍的AOP(方法织入)。而不是成为像AspectJ一样的AOP方案
- 因为AspectJ在实际运行之前就完成了织入,所以说它生成的类是没有额外运行时开销的
下表总结了 Spring AOP 和 AspectJ 之间的关键区别: