Spring AOP拦截 EL 表达式实现方法日志记录
需积分: 50 105 浏览量
更新于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语法并将其与自定义注解、切面和参数名称关联起来。通过这种方式,我们可以灵活地在不改变原有代码结构的情况下,动态地控制业务逻辑的执行流程。
1083 浏览量
2024-09-10 上传
1382 浏览量
2016-12-07 上传
130 浏览量
点击了解资源详情
点击了解资源详情