在前面我们介绍了SpEl(Spring Expression Language)解析与Spring SpEl高级语法,但是SpEl在时间的开发中能帮助我们做些什么呢?该如何与自己的业务进行匹配呢?本讲将介绍一种使用方式,Aop + SpEl实现日志记录!主要是通过SpEl实现自定义的记录.Aop大家应该都很熟悉,这里不做过多介绍,如果不是很了解,可以先阅读Spring Aop 核心概念 ,下面我将进行核心的业务开发。
自定义注解
我们将自定义一个注解,用与拦截
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DemoLog {
String name() default "demo";
String el();
}
复制
Aop 实现
这里我们采用@Around的方式,在方法前进行监听,与发生异常时进行监听
@Slf4j
@Aspect
@Component
public class LogAspect {
@Pointcut(value = "@annotation(DemoLog)")
public void logAspect() {
}
/**
* 环绕处理
*
* @param joinPoint
* @throws Throwable
*/
@Around(value = "logAspect()")
public Object getAroundLog(ProceedingJoinPoint joinPoint) throws Throwable {
Object proceed;
try {
//前置处理
saveLogAspect(joinPoint, null);
proceed = joinPoint.proceed();
return proceed;
} catch (Throwable throwable) {
saveLogAspect(joinPoint, throwable);
throw new RuntimeException(throwable.getMessage());
}
}
private void saveLogAspect(JoinPoint joinPoint, Throwable throwable) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
try {
// 获取自定义注解
DemoLog demoLog = methodSignature.getMethod().getAnnotation(DemoLog.class);
if (Objects.nonNull(demoLog)) {
Object spEl = AspectExpress.getSpEl(joinPoint, methodSignature, demoLog.el(), Object.class);
if (log.isInfoEnabled()) {
log.info(" SpelLog {}", spEl);
}
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
复制
自定义 SpEl解析器
我们通过自定义SpEL解析的方式实现
public class AspectExpress {
public static <T> T getSpEl(JoinPoint joinPoint, MethodSignature methodSignature, String el, Class<T> clazz){
EvaluationContext context = getContext(joinPoint.getArgs(), methodSignature.getMethod());
return getValue(context, el, clazz);
}
/**
* 获取spel 定义的参数值
*
* @param context 参数容器
* @param key key
* @param clazz 需要返回的类型
* @param <T> 返回泛型
* @return 参数值
*/
private static <T> T getValue(EvaluationContext context, String key, Class<T> clazz) {
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
Expression expression = spelExpressionParser.parseExpression(key);
return expression.getValue(context, clazz);
}
/**
* 获取参数容器
*
* @param arguments 方法的参数列表
* @param signatureMethod 被执行的方法体
* @return 装载参数的容器
*/
private static EvaluationContext getContext(Object[] arguments, Method signatureMethod) {
String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(signatureMethod);
if (parameterNames == null) {
throw new RuntimeException("参数列表不能为null");
}
EvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < arguments.length; i++) {
context.setVariable(parameterNames[i], arguments[i]);
}
return context;
}
}
复制
使用方式
@RestController
public class SpElDemo {
@DemoLog(el = "#id")
@GetMapping(value = "spel/demo/{id}")
public void get(@PathVariable("id") Integer id){
}
@DemoLog(el = "#user.name")
@GetMapping(value = "spel/demo")
public void get(SecurityProperties.User user){
}
}
复制
加上以SpEl的功能可以让我们的Aop操作更加强大。也可以实现更多的处理,可以是我们的日志更加丰富
文章转载自Java有货,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
2025年4月中国数据库流行度排行榜:OB高分复登顶,崖山稳驭撼十强
墨天轮编辑部
2330次阅读
2025-04-09 15:33:27
数据库国产化替代深化:DBA的机遇与挑战
代晓磊
1076次阅读
2025-04-27 16:53:22
2025年3月国产数据库中标情况一览:TDSQL大单622万、GaussDB大单581万……
通讯员
671次阅读
2025-04-10 15:35:48
数据库,没有关税却有壁垒
多明戈教你玩狼人杀
538次阅读
2025-04-11 09:38:42
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
515次阅读
2025-04-14 09:40:20
最近我为什么不写评论国产数据库的文章了
白鳝的洞穴
475次阅读
2025-04-07 09:44:54
2025年4月国产数据库中标情况一览:4个千万元级项目,GaussDB与OceanBase大放异彩!
通讯员
436次阅读
2025-04-30 15:24:06
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
432次阅读
2025-04-17 17:02:24
天津市政府数据库框采结果公布,7家数据库产品入选!
通讯员
408次阅读
2025-04-10 12:32:35
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
349次阅读
2025-04-18 10:01:22