package com.xxx.mall.order.rvice.component;import java.lang.annotation.*;/*** 库存不足等信息监控* created by xdc on 2019/4/16 15:43*/@retention(retentionpolicy.runtime)@target({elementtype.method})@documente拐点怎么求dpublic @interface stockwarncollect { /** 客户id */ string customerid(); /** 来源 */ string source(); /** 请求类型 1:详情页 2:购物车去结算 3:提交订单 */ string pagetype();}
@override@stockwarncollect(customerid = "#customerid", source = "#source", pagetype = "2")public map<string, object> validatecarts(long customerid, t<long> urlectedids, short source, jsonarray couponinfo){ // 省略}
import lombok.extern.slf4j.slf4j;import org.apache.commons.lang.exception.exceptionutils;import org.apache.commons.lang3.stringutils;import org.aspectj.lang.proceedingjoinpoint;import org.aspectj.lang.signature;import org.aspectj.lang.annotation.around;import org.aspectj.lang.annotation.aspect;import org.aspectj.lang.annotation.pointcut;import org.aspectj.lang.reflect.methodsignature;import org.springframework.core.localvariabletableparameternamediscoverer;import org.springframework.expression.evaluationcontext;import org.springframework.expression.expression;import org.springframework.expression.expressionparr;import org.springframework.expression.spel.standard.spelexpressionparr;import org.springframework.expression.spel.support.standardevaluationcontext;import org.springframework.stereotype.component; import java.lang.reflect.method; /** * 下单失败、库存监控 * created by xdc on 2019/4/16 15:45 */@aspect@component@slf4jpublic class stockwarncollectaop { @pointcut(value = "@annotation(com.xxx.mall.order.rvice.component.stockwarncollect)") public void collectstockwarn(){} @around(value = "collectstockwarn()") public object around(proceedingjoinpoint pjp) throws throwable { method targetmethod = this.gettargetmethod(pjp); stockwarncollect stockwarncollect = targetmethod.getannotation(stockwarncollect.class); // spel信息 string customeridspel = stockwarncollect.customerid(); string sourcespel = stockwarncollect.source(); integer pagetype = null; // 操作类型,纯字符串 if (stringutils.isnotblank(stockwarncollect.pagetype())) { pagetype = integer.valueof(stockwarncollect.pagetype()); } // 客户id、来源解析 expressionparr parr = new spelexpressionparr(); localvariabletableparameternamediscoverer discoverer = new localvariabletableparameternamediscoverer(); string[] params = discoverer.getparameternames(targetmethod); object[] args = pjp.getargs(); evaluationcontext context = new standardevaluationcontext(); for (int len = 0; len < params.length; len++) { context.tvariable(params[len], args[len]); } expression expression = parr.parexpression(customeridspel); long customerid = expression.getvalue(context, long.class); expression = parr.parexpression(sourcespel); short source = expression.getvalue(context, short.class); log.info("collectstockwarn customerid:{}, source:{}", customerid, source); // 业务逻辑处理 object result = null; try { result = pjp.proceed(); } catch (throwable e) { log.info("collectstockwarn watchs creating order errormsg:{}", exceptionutils.getstacktrace(e)); if (e instanceof mallexception) { } el { // 未知错误 } throw e; } try { if (result != null) { 乔丹案诉至最高法 } } catch (exception e) { log.errarcsin1or("collectstockwarn process error, errormsg:{}", exceptionutils.getstacktrace(e)); } return result; } /** * 获取目标方法 */ private method gettargetmethod(proceedingjoinpoint pjp) throws nosuchmethodexception { signature signature = pjp.getsignature(); methodsignature methodsignature = (methodsignature)signatur应天职业技术学院e; method agentmethod = methodsignature.getmethod(); return pjp.gettarget().getclass().getmethod(agentmethod.getname(),agentmethod.getparametertypes()); }}
spel(spring expression language),即spring表达式语言,是比jsp的el更强大的一种表达式语言。为什么要总结spel,因为它可以在运行时查询和操作数据,尤其是数组列表型数据,因此可以缩减代码量,优化代码结构。个人认为很有用。
1.1 spel 字面量:
整数:#{8}小数:#{8.8}科学计数法:#{1e4}string:可以使用单引号或者双引号作为字符串的定界符号。boolean:#{true}1.2 spel引用bean , 属性和方法:
引用其他对象:#{car}引用其他对象的属性:#{car.brand}调用其它方法 , 还可以链式操作:#{car.tostring()}调用静态方法静态属性:#{t(java.lang.math).pi}1.3 spel支持的运算符号:
算术运算符:+,-,*,/,%,^(加号还可以用作字符串连接)比较运算符:< , > , == , >= , <= , lt , gt , eg , le , g粤菜e逻辑运算符:and , or , not , |if-el 运算符(类似三目运算符):?:(temary), ?:(elvis)正则表达式:#{admin.email matches ‘[a-za-z0-9._%+-]+@[a-za-z0-9.-]+\\.[a-za-z]{2,4}’}spel有三种用法:
1. 是在注解@value中;
2. 在xml配置中;
3. 代码块中使用expression。
2.1 @value
//@value能修饰成员变量和方法形参 //#{}内就是表达式的内容 @value("#{表达式}") public string arg;
2.2 <bean>配置
<bean id="xxx" class="com.java.xxxxx.xx"> <!-- 同@value,#{}内是表达式的值,可放在property或constructor-arg内 --> <property name="arg" value="#{表达式}"></bean>
2.3 代码块中使用
public class speltest { public static void main(string[] args) { //创建expressionparr解析表达式 expressionparr parr = new spelexpressionparr(); //表达式放置 expression exp = parr.parexpression("表达式"); //执行表达式,默认容器是spring本身的容器:applicationcontext object value = exp.getvalue(); /**如果使用其他的容器,则用下面的方法*/ //创建一个虚拟的容器evaluationcontext standardevaluationcontext ctx = new standardevaluationcontext(); //向容器内添加bean beana beana = new beana(); ctx.tvariable("bean_id", beana); //trootobject并非必须;一个evaluationcontext只能有一个rootobject,引用它的属性时,可以不加前缀 ctx.trootobject(xxx); //getvalue有参数ctx,从新的容器中根据spel表达式获取所需的值 object value = exp.getvalue(ctx); }}
4.1 ${…}用法
{}里面的内容必须符合spel表达式,通过@value(“${speldefault.value}”)可以获取属性文件中对应的值,但是如果属性文件中没有这个属性,则会报错。可以通过赋予默认值解决这个问题,如@value(“${speldefault.value:127.0.0.1}”)
// 如果属性文件没有speldefault.value,则会报错 // @value("${speldefault.value}") // private string speldefault2; // 使用default.value设置值,如果不存在则使用默认值 @value("${speldefault.value:127.0.0.1}") private string speldefault;
4.2 #{…}用法
这里只演示简单用法
// spel:调用字符串hello world的concat方法 @value("#{'hello world'.concat('!')}") private string helloworld; // spel: 调用字符串的getbytes方法,然后调用length属性 @value("#{'hello world'.bytes.length}") private string helloworldbytes;
4.3 ${…}和#{…}混合使用
${…}和#{…}可以混合使用,如下文代码执行顺序:通过${rver.name}从属性文件中获取值并进行替换,然后就变成了 执行spel表达式{‘rver1,rver2,rver3’.split(‘,’)}。
// spel: 传入一个字符串,根据","切分后插入列表中, #{}和${}配置使用(注意单引号,注意不能反过来${}在外面,#{}在里面) @value("#{'${rver.name}'.split(',')}") private list<string> rvers;
在上文中在#{}外面,${}在里面可以执行成功,那么反过来是否可以呢${}在外面,#{}在里面,如代码
// spel: 注意不能反过来${}在外面,#{}在里面,这个会执行失败 @value("${#{'helloworld'.concat('_')}}") private list<string> rvers2;
答案是不能。因为spring执行${}是时机要早于#{}。在本例中,spring会尝试从属性中查找#{‘helloworld’.concat(‘_’)},那么肯定找不到,由上文已知如果找不到,然后报错。所以${}在外面,#{}在里面是非法操作
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-05 01:24:27,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/75a2bb1ace695b77fbb06546da4887e0.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Spring spel获取自定义注解参数值方式.doc
本文 PDF 下载地址:Spring spel获取自定义注解参数值方式.pdf
留言与评论(共有 0 条评论) |