文章目录
- AOP介绍
- AOP的核心概念
- 切面(Aspect)
- 切点(Join Point)
- 语法具体解释
- 增强(Advice)
- 织入(weaving)
- 相应实现
- 权限校验
- 日志输出
AOP介绍
AOP全称Aspect Oriented Programming意为面向切面编程,通过预编译和运行期间通过动态代理来实现程序功能统一维护的技术。AOP思想是OOP[面向对象]的延续,在OOP中以类[class]作为基本单元, 而 AOP中的基本单元是 Aspect[切面],AOP是软件行业的热点,也是Spring框架中的一个重要内容。
与前端中的组件化差不多意思,每个组件负责自己的视图和逻辑,将重复的功能提炼成一个切面
AOP的核心概念
切面(Aspect)
切面是 AOP 的基本构成单位,它定义了一组横切关注点的处理逻辑。例如,日志记录、事务管理、安全检查等都可以被视为切面。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LoggingAspect { // 前置增强 @Before("execution(* com.example.service.*.*(..))") public void logBefore() { System.out.println("Executing method..."); } // 后置增强 @After("execution(* com.example.service.*.*(..))") public void logAfter() { System.out.println("Method execution finished."); } // 环绕增强 @Around("execution(* com.example.service.*.*(..))") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Before method: " + joinPoint.getSignature()); Object result = joinPoint.proceed(); // 执行方法 System.out.println("After method: " + joinPoint.getSignature()); return result; }
}
切点(Join Point)
切点是程序执行中的特定位置,如方法调用、对象创建等。AOP 允许在这些切点上插入增强逻辑。
execution(* com.example.service.*.*(..))
是一个切点表达式,表示我们在 com.example.service
包中所有方法的调用位置上织入增强。
语法具体解释
execution(<修饰符><返回类型><包.类.⽅法(参数)><异常>)
修饰符与异常一般省略
*
:- 匹配任意字符,通常用于匹配包名、类名或方法名。例如,
com.example.*
可以匹配com.example.service
、com.example.controller
等包名。
- 匹配任意字符,通常用于匹配包名、类名或方法名。例如,
..
:- 匹配任意层级的包名或类名,可以用来匹配多个元素。在表示类时,通常需要和
*
一起使用。例如,com.example..*
可以匹配com.example.service.UserService
、com.example.controller.OrderController
等。
- 匹配任意层级的包名或类名,可以用来匹配多个元素。在表示类时,通常需要和
+
:- 表示匹配某个类及其所有子类。这个符号必须跟在类名后面。例如,
com.example.service.IUserService+
匹配IUserService
类及其所有实现类。
- 表示匹配某个类及其所有子类。这个符号必须跟在类名后面。例如,
增强(Advice)
增强已经在 LoggingAspect
类中定义,包括:
logBefore()
是前置增强,在方法执行前调用。logAfter()
是后置增强,在方法执行后调用。logAround()
是环绕增强,可以在方法执行前后自定义行为。
织入(weaving)
织入(Weaving)是面向切面编程(AOP)中的一个核心概念,指的是将切面(Aspect)与目标对象(Target Object)结合的过程。
- 编译时织入:在代码编译时,编译器将切面逻辑嵌入到目标类中。这种方式通常需要使用特定的编译器工具,比如 AspectJ。
- 类加载时织入:在类加载时,Java 虚拟机(JVM)会对类进行修改,将切面逻辑插入到目标类中。
- 运行时织入:在运行时,AOP 框架(如 Spring AOP)通过代理技术将切面逻辑动态地附加到目标方法上。这是 Spring AOP 中最常用的方法,通常涉及创建一个代理对象来包装目标对象,所有对目标对象方法的调用都通过代理对象进行,从而实现增强功能。
织入是 AOP 的关键机制,允许开发者在不修改业务逻辑的情况下,灵活地添加跨越多个模块的功能,比如日志、事务处理、安全控制等。
相应实现
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
权限校验
@Aspect
@Component
public class PremissionAdvice { @Before("execution(* com.stt.aop.service.IUserService.addUser(..)) " + "|| execution(* com.stt.aop.service.IUserService.deleteUser(..)) " + "|| execution(* com.stt.aop.service.IUserService.updateUser(..))") public void checkPre() { System.out.println("权限校验》"); } }
日志输出
@Aspect
@Component
public class LoggingAdvice { // 单独配置切入点 @Pointcut("execution(* com.stt.aop.service.IUserService.*(..))") public void afterLog(){} // 扩展功能的方法称为:增强/通知 // 1、确定要增强到哪些方法上 // 2、确定在方法执行之前,还是执行之后,还是前后都需要,还是报异常时需要 @After("afterLog()") public void printLog() { System.out.println("操作时间======》" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } // 在之前也需要打印日志 @Before("afterLog()") public void printLogBefore() { System.out.println("操作时间======》" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } }
文章到这里就结束了,希望对你有所帮助