Spring Aop中解析spel表达式,实现更灵活的功能
前言
在Spring Aop中,我们可以拿到拦截方法的参数,如果能结合spel表达式,就能实现更加灵活的功能。典型的实现有Spring的缓存注解:
@Cacheable(value = "user", key = "#id", condition = "#id lt 10")
public User conditionFindById(final Long id) {
}
复制代码
@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
public User save(User user) {
复制代码
本文介绍如何在aop编程中解析spel表达式,提供几个通用的方法。
Spring使用自定义注解实现aop的方式这里就不赘述,只着重介绍如何解析spel。
准备
实现非常简单,Spring本身就提供了简便的api,我们只需要获取:
- 方法:
Method method
- 方法参数:
Object[] arguments
- spel表达式:
String spel
这些都能从aop入口方法的参数ProceedingJoinPoint
中得到。
spel表达式显然就是从自定义注解中获取了,而获取方法和参数的方式如下:
获取方法:
private Method getMethod(ProceedingJoinPoint joinPoint) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();if (method.getDeclaringClass().isInterface()) {try {method = joinPoint.getTarget().getClass().getDeclaredMethod(joinPoint.getSignature().getName(),method.getParameterTypes());} catch (SecurityException | NoSuchMethodException e) {throw new RuntimeException(e);}}return method;}
复制代码
获取方法参数值:
Object[] arguments = joinPoint.getArgs();
复制代码
解析
然后就是解析spel表达式,首先在aop类中定义两个属性:
private ExpressionParser parser = new SpelExpressionParser();private LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
复制代码
根据spel表达式解析参数,得到结果:
/*** 解析 spel 表达式** @param method 方法* @param arguments 参数* @param spel 表达式* @param clazz 返回结果的类型* @param defaultResult 默认结果* @return 执行spel表达式后的结果*/private <T> T parseSpel(Method method, Object[] arguments, String spel, Class<T> clazz, T defaultResult) {String[] params = discoverer.getParameterNames(method);EvaluationContext context = new StandardEvaluationContext();for (int len = 0; len < params.length; len++) {context.setVariable(params[len], arguments[len]);}try {Expression expression = parser.parseExpression(spel);return expression.getValue(context, clazz);} catch (Exception e) {return defaultResult;}}
复制代码
总结
上述就是整个解析spel表达式的关键流程,整体来看,aop类的结构是这样的:
@Aspect
public class SpelAspect {private ExpressionParser parser = new SpelExpressionParser();private LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();@Around(value = "@annotation(自定义注解)")public Object test(ProceedingJoinPoint point) throws Throwable {Object obj;// 获取方法参数值Object[] arguments = point.getArgs();// 获取方法Method method = getMethod(point);// 从注解中获取spel字符串,省略...String spel = ...// 解析spel表达式Boolean result = parseSpel(method, arguments, spel, Boolean.class, Boolean.FALSE);// 业务操作,省略......return point.proceed();}
}
复制代码
以上提供一个基本思路和几个通用的方法(#getMethod
、#parseSpel
),接下来就是大家发挥想象力的时间啦!
阅读原文
Spring Aop中解析spel表达式,实现更灵活的功能相关推荐
- 说说如何在 Spring 框架中使用 SpEL 表达式
在 Spring 框架的 XML 配置方式或者注解配置方式中,我们都可以使用 SpEL 表达式,它们的语法都是 #{表达式}. 1 基于 XML 配置 在 XML 配置中,我们可以通过 SpEL 表达 ...
- Spring AOP中pointcut expression表达式解析 及匹配多个条件
(* com.evan.crm.service.*.*(..))中几个通配符的含义: |第一个 * -- 通配 随便率性返回值类型| |第二个 * -- 通配包com.evan.crm.servic ...
- Spring AOP中pointcut expression表达式解析
Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&am ...
- Spring AOP中@Pointcut切入点表达式详解
目录 一.瞅一眼标准的AspectJ Aop的pointcut的表达式 二.SpringAop的十一种AOP表达式 三.演示使用 1.execution: 2.within: 3.this: 4.ta ...
- java args例子_Spring AOP中使用args表达式的方法示例
本文实例讲述了Spring AOP中使用args表达式的方法.分享给大家供大家参考,具体如下: 一 配置 xmlns:xsi="http://www.w3.org/2001/XMLSchem ...
- spring aop中pointcut表达式
spring aop中pointcut表达式 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @within ...
- Spring AOP中的静态代理和动态代理的原理和实践
对于最近博主最近写博客的兴致大发,我也在思考:为什么而写博客?在互联网时代,无论你是牛人大咖,还是小白菜鸟,都有发表自己看法的权利.无论你是对的还是错的,都会在这个平台上找到答案.所以,我会尽可能去写 ...
- Spring AOP中定义切点(PointCut)和通知(Advice)
本文讨论一下Spring AOP编程中的两个关键问题,定义切点和定义通知,理解这两个问题能应付大部分AOP场景. 如果你还不熟悉AOP,请先看AOP基本原理,本文的例子也沿用了AOP基本原理中的例子. ...
- Spring AOP中定义切点PointCut详解
1.AOP是什么? 软件工程有一个基本原则叫做"关注点分离"(Concern Separation),通俗的理解就是不同的问题交给不同的部分去解决,每部分专注于解决自己的问题.这年 ...
最新文章
- java oralce merge_mybatis 使用oracle merge into 语句踩坑实录(示例代码)
- SDCC 2015架构专场札记:一线互联网公司的架构实践
- Java函数式接口看这一篇就够了
- binaryreader java,C# 二进制文件的读写 | 菜鸟教程
- java猜单词游戏_序列应用——猜单词游戏
- liunx驱动----异步通知
- Ubuntu 12.10连接米2
- 工作资讯002---FaaS和PaaS的关系_Iaas_Paas_Saas
- 第四届泰迪杯数据挖掘挑战赛B题数据预处理-数据导入(Matlab)
- GEE植被覆盖度计算
- 总结 工作法(时间管理+复盘)
- Arcgis中修改属性字段名
- 服务器bmc口装系统,IBM X3650服务器BMC安装系统
- 导弹巡航追踪目标模拟程序(1)源码版--matlab
- CMD的打开方式以及一些常用的Dos命令
- Light OJ 1138
- 使用TestFlight安装ios APP的测试版本
- kafka的Rebalance问题分析(续)
- NSD Devops day03
- SVN图标消失解决方案