何为AOP
AOP(Aspect Oriented Programming)⾯向切⾯编程。
OOP(Object Oriented Programming)⾯向对象编程,⽤对象化的思想来完成程序。
AOP 是对 OOP 的⼀个补充,是在另外⼀个维度上抽象出对象。
具体是指程序运⾏时动态地将⾮业务代码切⼊到业务代码中,从⽽实现程序的解耦合,将⾮业务代码抽
象成⼀个对象,对对象编程就是⾯向切⾯编程。
按每个方法,如增删查改,在每个方法上新增代码(冗余),如图:
使用AOP进行优化后,如图:
原理图
## 使用
1. 创建自定义注解
创建一个Annotation的类
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogSet{
String value() default "";
}
2.导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
3.切面对应类
@Component
@Aspect
public class LogSetAspect(){
private static final Logger log = LoggerFactory.getLogger(LogTrackAspect.class);
//这个是将自己自定义注解作为切点的根据,即第一步的LogSet类。
@Pointcut(value = "@annotation(com.jc.mytest.aop.logRecord.LogTrack)")
public void pointCut(){
}
//在切面切入目标方法之前执行
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint){
// 可以用来记录一些信息,比如获取请求的 URL 和 IP
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 获取请求 URL
String url = request.getRequestURL().toString();
// 获取请求 IP
String ip = request.getRemoteAddr();
}
//方法在切面切入目标方法之后执行
@After("pointCut()")
public void doAfter(JoinPoint joinPoint) {
log.info("==== doAfter 方法进入了====");
Signature signature = joinPoint.getSignature();
String method = signature.getName();
log.info("方法{}已经执行完", method);
}
//可以用来捕获切入方法执行完之后的返回值,对返回值进行业务逻辑上的增强处理
@AfterReturning(pointcut = "pointCut()", returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result){
}
//该方法中可以做一些异常的处理逻辑。要注意的是 throwing 属性的值必须要和参数一致,否则会报错
@AfterThrowing(pointcut = "pointCut()", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
Signature signature = joinPoint.getSignature();
String method = signature.getName();
// 处理异常的逻辑
log.info("执行方法{}出错,异常为:{}", method, ex);
}
//可自由选择切入的时机和执行顺序,但通常需要在线程安全的环境下使用。
}