文章目录
-
-
- AOP介绍
- AOP的核心概念
-
- 切面(Aspect)
- [切点(Join Point)](#切点(Join Point))
- 增强(Advice)
- 织入(weaving)
- 相应实现
-
AOP介绍
AOP全称Aspect Oriented Programming意为面向切面编程 ,通过预编译和运行期间通过动态代理 来实现程序功能统一维护的技术。AOP思想是OOP[面向对象]的延续,在OOP中以类[class]作为基本单元, 而 AOP中的基本单元是 Aspect[切面],AOP是软件行业的热点,也是Spring框架中的一个重要内容。
与前端中的组件化差不多意思,每个组件负责自己的视图和逻辑,将重复的功能提炼成一个切面
AOP的核心概念
切面(Aspect)
切面是 AOP 的基本构成单位,它定义了一组横切关注点的处理逻辑。例如,日志记录、事务管理、安全检查等都可以被视为切面。
java
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 的关键机制,允许开发者在不修改业务逻辑的情况下,灵活地添加跨越多个模块的功能,比如日志、事务处理、安全控制等。
相应实现
xml
<dependency><groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
权限校验
java
@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("权限校验》");
}
}
日志输出
java
@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")));
}
}
文章到这里就结束了,希望对你有所帮助