我们进入ruoyi-framework,立刻看到的内容
了解一下aspectj 这个概念
面向切面编程(AOP)是一种编程范式,重点聚焦于软件应用程序中的关注点分离。AOP 背后的思想是软件应用程序具有多个切面,其中一些切面跨越了模块化编码的典型划分,就是可能多个模块化代码都会使用,导致代码分散和混乱。
在软件开发中,有些功能包括日志记录、安全检查、错误处理和数据验证。在面向对象编程 (OOP) 等传统编程范式中,这些横切关注点通常与核心业务逻辑纠缠在一起,导致代码难以维护和扩展。
AOP(Aspect Oriented Programming)面向切面编程的概念比较抽象,主要涉及下面这些术语:
一个目标类可以被多个切面切入,多个切面也可以切入一个目标类。
切面实现的本质是一个或多个基于连接点的拦截器。
AOP提供了一种分离关注点的新维度,AOP会将这些关注点模块成称为“切面”的单独单元,这些切面可以独立开发、测试和重用。然后,将它们在需要的地点“编织”到主代码库中,确保核心逻辑保持不变且连贯。这种编织可以在不同的时间发生:
- 编译时:编译应用程序时会编织各个切面。
- 加载时:加载应用程序类时会编织各个切面。
- 运行时:各个切面是在应用程序执行期间编织的。
JDK 动态代理通过实现接口生成代理类,使用拦截器加反射机制生成。
CGLIB 动态代理通过继承生成代理子类,使用字节码技术生成。通过子类对父类的方法进行重写来实现代理,因此,对 final 修饰的方法不能代理。
JDK提供了invocationHandler接口和Proxy类,借助这两个工具可以达到我们想要的效果。 如果想更深入的的了解动态原理的实现,可以参照 Java 动态代理作用是什么? - 知乎
若依的操作日志部分,注解此类 @Aspect ,简单粗暴,然后重写几个方法就可以
@Aspect
@Component
public class LogAspect
{
看几个方法,主要是 操作日志进行处理 SysOperLog 这是操作记录表,继承了BaseEntity,持久化到数据库里
@Before(value = "@annotation(controllerLog)")
public void boBefore(JoinPoint joinPoint, Log controllerLog)
{
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
{
handleLog(joinPoint, controllerLog, null, jsonResult);
}
/**
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
{
handleLog(joinPoint, controllerLog, e, null);
}
可以推测,在有注解@Log 的Controller(可以随便找几个,完成测试) 的方法里面,在其前面, 在执行完成以后,或者发生异常的时候,我们都在这个方法上做了日志记录,很容易理解 切面的好处,以及是如何使用的。
面向切面编程(AOP)是软件开发领域的游戏规则改变者。 @Aspect 和 @Pointcut 注解等工具,实现 AOP 变得更加简化,使开发人员能够专注于应用程序的核心逻辑,同时单独管理横切点。如果使用得当,这些注解可以带来更清晰、更易于维护和更高效的代码结构。