SPEL应用实战!
发表于更新于
SpEL
SpEL
即 Spring
表达式语言,可以在运行时评估表达式并生成值。
应用场景
动态参数配置:
可以通过 SpEL
将应用程序中的各种参数配置化。
通过动态配置,可以在运行时根据不同的环境或需求来进行灵活的参数设置。
运行时注入:
使用SpEL
,可以在运行时动态注入属性值,而不需要在编码时硬编码。
条件判断与业务逻辑:
SpEL
支持复杂的条件判断和逻辑计算,可以方便地在运行时根据条件来执行特定的代码逻辑。
表达式模板化:
SpEL
支持在表达式中使用模板语法,允许将一些常用的表达式作为模板。
系统场景
Excel 解析:
SpEL
可以用于解析 Excel
表格中的数据。
可以使用 SpEL
表达式来指定需要解析的单元格、行、列等等,提取数据并应用相应的逻辑。
规则引擎:
在使用规则引擎时,SpEL
可以用于定义规则条件和执行动作。
通过 SpEL
表达式,可以动态地根据特定的条件对数据进行处理和决策。
模板引擎:
SpEL
可以用于填充模板数据。
通过 SpEL
表达式,可以在模板中引用对象的属性、方法或函数。
配置文件解析:
SpEL
可以用于解析配置文件中的动态值。
通过 SpEL
表达式,可以在配置文件中引用其他属性或方法的值。
验证规则:
在数据验证的场景中,SpEL
可以用于定义验证规则。
通过 SpEL
表达式,可以对数据进行复杂的验证和处理。
简单举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public String spELSample(int number) { ExpressionParser parser = new SpelExpressionParser(); String expressionStr = "#number > 10 ? 'true' : 'false'"; Expression expression = parser.parseExpression(expressionStr);
StandardEvaluationContext context = new StandardEvaluationContext(); context.setVariable("number", number);
return expression.getValue(context, String.class); }
|
实现动态参数处理策略
举例:每新增一个渠道接入时不需要进行代码开发,只需在配置表中维护关联关系。
根据标识匹配对应策略标识,根据策略标识找到具体参数处理策略表达式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class ExpressionUtil { private final ExpressionParser expressionParser = new SpelExpressionParser();
public StandardEvaluationContext createContext(String instAccountNo){ StandardEvaluationContext context = new StandardEvaluationContext(); context.setVariable("instAccountNo", instAccountNo); this.registryFunction(context); return context; }
private void registryFunction(StandardEvaluationContext context) { try { context.addPropertyAccessor(new MapAccessor()); context.registerFunction("yuanToCent", ExpressionHelper.class.getDeclaredMethod("yuanToCent", String.class)); context.registerFunction("substringBefore", StringUtils.class.getDeclaredMethod("substringBefore",String.class,String.class)); } catch (Exception e) { log.info("SpEL函数注册失败:", e); } }
@Cacheable(key="'getExpressionWithCache:'+#cacheKey", unless = "#result == null") public Expression getExpressionWithCache(String cacheKey, String expressionString) { try { return expressionParser.parseExpression(expressionString); } catch (Exception e) { log.error("SpEL表达式解析异常,表达式:[{}]", expressionString, e); throw new BizException(ReturnCode.EXCEPTION.getCode(),String.format("SpEL表达式解析异常:[%s]",expressionString),e); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class ExpressionService { @Resource private ExpressionUtil expressionUtil;
public FileBillReqDTO transform(ChannelEntity channel, String instAccountNo) throws Exception { StandardEvaluationContext context = expressionUtil.createContext(instAccountNo); FileBillReqDTO target = ClassHelper.newInstance(FileBillReqDTO.class); for (ChannelApiEntity api : channel.getApis()) { Field field = ReflectionUtils.findField(FileBillReqDTO.class, api.getFieldCode()); String expressionString = api.getFieldExpression(); Expression expression = expressionUtil.getExpressionWithCache(api.fieldExpressionKey(), expressionString); Object value = expression.getValue(context, FileBillReqDTO.class); field.setAccessible(true); field.set(target, value); } return target; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class ChannelApplyFileClient { @Resource private CNRegionDataFetcher cnRegionDataFetcher; @Resource private ExpressionService expressionService; @Resource private ChannelRepository channelRepository;
public String applyFileBill(String instCode, String instAccountNo) { ChannelEntity channel = channelRepository.findByInstCode(instCode); FileBillReqDTO channelReq = expressionService.transform(channel, instAccountNo); BaseResult<FileBillResDTO> result = cnRegionDataFetcher.applyFileBill(channelReq, "资金账单下载"); return "处理中"; } }
|
Excel解析
举例:从不同的渠道下载账单,并对账单进行解析,解析后的数据落入流水表。
注意不同渠道的账单的头字段和格式存在差异。
传统的方式中,解析 Excel
通常需要通过创建实体类来映射 Excel
的结构和数据。
每个实体类代表一个 Excel
行或列,需要手动编写代码来将 Excel
数据解析为相应的实体对象。
以下是使用 SpEL
方式动态解析 Excel
的一般步骤:
- 使用
Apache POI
等工具读取 Excel
数据表。
- 根据配置表,将
Excel
中的列与 SpEL
表达式进行关联。
- 使用
SpEL
解析器,在运行时解析这些 SpEL
表达式。
- 将解析后的结果做数据清洗后落表,应用于现金流打标业务。