统一记录日志,可能会想到封装一个记日志的组件,在每个业务中调用,但是这样实现不利于维护,这里就需要AOP技术。
**AOP的概念 **
- Aspect Oriented Programing, 即面向方面(切面)编程。
- AOP是一种编程思想,是对OOP的补充, 可以进一步提高编程的效率。
Target:目标对象,也就是我们实现的业务,有很多地方可以织入代码
Aspect:切面组件,pointcut声明织入到哪些目标的哪些织入点,advice具体的逻辑
JoinPoint:织入点
三种织入时机,编译装载运行时织入,各有优点,编译时织入可能有一些数据等还不知道,运行时有可能影响速度。
AOP的实现
- AspectJ
- AspectJ是语言级的实现,它扩展了Java语言,定义了AOP语法。
- AspectJ在编译期织入代码,它有一个专门的编译器,用来生成遵守Java字节码规范的class文件。
- Spring AOP
- Spring AOP使用纯Java实现,它不需要专门的编译过程,也不需要特殊的类装载器。
- Spring AOP在运行时通过代理的方式织入代码,只支持方法类型的连接点。
- Spring支持对AspectJ的集成。
**Spring AOP **
- JDK动态代理
- Java提供的动态代理技术,可以在运行时创建接口的代理实例。
- Spring AOP默认采用此种方式,在接口的代理实例中织入代码。
- CGLib动态代理
- 采用底层的字节码技术,在运行时创建子类代理实例。
- 当目标对象不存在接口时,Spring AOP会采用此种方式,在子类实例中织入代码。
AOP示例
新建一个aspect包,然后新建AlphaAspect类。
- 使用@Component和@Aspect注解修饰类
- 使用@Pointcut定义连接点,execution固定关键字,*表示任何方法返回值都行,com.neu.langsam.community.service.*表示service包下所有类,再.*表示所有方法,(…)表示所有的参数都要处理,也可以指定明确的方法
- 五种注解实现五种通知,前四个实现大同小异,around表示前后都执行,实现方法就是传入joinPoint,调用joinPoint的proceed方法,也就是业务方法,在调用前后写需要织入的逻辑。
package com.neu.langsam.community.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AlphaAspect {
@Pointcut(