Spring AOP拦截 EL 表达式实现方法日志记录
需积分: 50 65 浏览量
更新于2024-09-10
收藏 194KB DOCX 举报
在AOP(面向切面编程)中,EL表达式是一种强大的工具,特别是在Spring框架中用于动态地根据业务规则进行决策。本文档探讨了如何利用自定义注解和切面来实现对Service层方法中特定条件的拦截,如当方法参数的值大于0.5时,执行日志输出。以下详细介绍了实现这一功能的步骤和注意事项。
首先,自定义一个名为`Log`的注解,它有两个属性:`spel`用于存储SpEL(Spring Expression Language)表达式,该表达式用于判断是否满足日志记录的条件;`desc`是一个可选的描述字段,用于提供额外的信息。注解的目标是`ElementType.METHOD`,表示它用于修饰方法,且`RetentionPolicy.RUNTIME`确保注解在运行时也能被访问。
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String spel() required; // 必须提供SpEL表达式
String desc() default "描述"; // 默认描述信息
}
```
在Service层,我们可以在需要进行日志拦截的方法上添加`@Log`注解,例如:
```java
@Service
public class MyService {
@Log(spel="#param.value > 0.5", desc="参数值大于0.5时输出日志")
public void doSomething(double param) {
// 方法体...
}
}
```
接下来,我们需要创建一个切面类`LogAspect`,这是一个`@Aspect`注解的组件,它将在Spring容器中自动注册。在这个切面中,我们将使用`SpelExpressionParser`解析`spel`属性中的表达式,并使用`LocalVariableTableParameterNameDiscoverer`来获取当前方法的参数名,以便在表达式中引用。
```java
@Component
@Aspect
public class LogAspect {
private final ExpressionParser parser = new SpelExpressionParser();
private final LocalVariableTableParameterNameDiscoverer discoverer;
public LogAspect() {
this.discoverer = new LocalVariableTableParameterNameDiscoverer();
}
@Around("@annotation(log)")
public Object logExecution(ProceedingJoinPoint joinPoint, Log log) throws Throwable {
// 解析SpEL表达式
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String paramName = discoverer.getParameterName(signature);
Object paramValue = joinPoint.getArgs()[signature.getParameterIndex(paramName)];
// 获取表达式的值
boolean shouldLog = parser.parseExpression(log.spel()).getValue(Boolean.class, paramValue);
if (shouldLog) {
// 输出日志
System.out.println("日志记录:调用方法[" + signature.getMethod().getName() + "],参数[" + paramValue + "]大于0.5");
}
// 执行原始方法
return joinPoint.proceed();
}
}
```
难点在于如何在切面中获取到具体的方法名,这里通过`LocalVariableTableParameterNameDiscoverer`实现了这一点。在切面的`around`方法中,首先解析SpEL表达式,然后检查其结果是否为`true`,如果是,则执行日志记录。
总结起来,实现AOP拦截EL表达式的关键在于理解SpEL语法并将其与自定义注解、切面和参数名称关联起来。通过这种方式,我们可以灵活地在不改变原有代码结构的情况下,动态地控制业务逻辑的执行流程。
2018-07-30 上传
2023-07-10 上传
2024-09-10 上传
2023-07-10 上传
2023-05-12 上传
2024-08-21 上传
2023-05-25 上传
xiaonan830203
- 粉丝: 1
- 资源: 3
最新资源
- C语言数组操作:高度检查器编程实践
- 基于Swift开发的嘉定单车LBS iOS应用项目解析
- 钗头凤声乐表演的二度创作分析报告
- 分布式数据库特训营全套教程资料
- JavaScript开发者Robert Bindar的博客平台
- MATLAB投影寻踪代码教程及文件解压缩指南
- HTML5拖放实现的RPSLS游戏教程
- HT://Dig引擎接口,Ampoliros开源模块应用
- 全面探测服务器性能与PHP环境的iprober PHP探针v0.024
- 新版提醒应用v2:基于MongoDB的数据存储
- 《我的世界》东方大陆1.12.2材质包深度体验
- Hypercore Promisifier: JavaScript中的回调转换为Promise包装器
- 探索开源项目Artifice:Slyme脚本与技巧游戏
- Matlab机器人学习代码解析与笔记分享
- 查尔默斯大学计算物理作业HP2解析
- GitHub问题管理新工具:GIRA-crx插件介绍