Aop

tim-qtp...大约 2 分钟Spring框架

1、基础概念:

aop就是面向切面编程,它是为了解耦而生的;我们在做业务逻辑代码开发的时候,可以在不改动原本代码的前提下,进行植入。

减少重复代码,抽取公共方法,每次调用方法前自动调用;

就像大楼,有主体,楼梯,电梯等;但是为了提高安全性和舒适性吧,加入了防火系统,中央空调和网络基础设施。都可以在原来基础上添加功能。

在平时开发中主要用于日志,权限控制,事务管理,统一异常处理

实现方式:动态代理,其实就是夹带私活。

具体怎么写

AOP 的核心概念

直接用代码解释吧

首先,定义一个简单的服务类:

public class UserService {
    public void createUser(String username) {
        System.out.println("创建用户:" + username);
    }
}

接下来,定义一个切面,用于在方法执行前后记录日志:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LoggingAspect {

    @Around("execution(* UserService.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("方法开始执行:" + joinPoint.getSignature().getName());
        Object result = joinPoint.proceed();
        System.out.println("方法执行结束:" + joinPoint.getSignature().getName());
        return result;
    }
    
    //还可以这么定义切入点
    @Pointcut("execution(* UserService.*(..))")
	public void inUserService() {}
}

在上述代码中:

  • 切面(Aspect)LoggingAspect 类通过 @Aspect 注解定义为一个切面。
  • 切入点(Pointcut)@Around("execution(* UserService.*(..))") 定义了一个切入点,表示匹配 UserService 类中所有方法的执行。
  • 通知(Advice)logAround 方法是一个环绕通知,在匹配的连接点前后执行。
  • 连接点(Join Point)UserService 类中的每个方法执行都是一个连接点。
  • 目标对象(Target Object)UserService 类的实例是目标对象。
  • 织入(Weaving):在运行时,AOP 框架将 LoggingAspect 切面织入到 UserService 的方法调用中。

Spring AOP默认用的是什么动态代理,两者的区别?

Spring Framework 默认使用的动态代理是 JDK 动态代理,SpringBoot 2.x 版本的默认动态代理是 CGLIB。

为什么使用CGLIB呢,因为使用JDK动态代理时,没有接口会报错,虽然效果差不多,但是CGLIB更方便

  • JDK动态代理只能代理实现了接口的类。它通过反射机制在运行时创建一个实现了指定接口的代理对象

  • CGLIB通过生成目标类的子类来实现代理,因此可以代理没有实现接口的类。CGLIB的性能通常优于JDK动态代理,因为它是通过字节码生成的,避免了反射的开销,CGLIB不能代理final类和final方法,因为它无法继承这些类和方法