首页 > 作文

Spring spel获取自定义注解参数值方式

更新时间:2023-04-05 01:24:29 阅读: 评论:0

目录
spel获取自定义注解参数值1.注解类2.注解使用3.aop中处理spel在注解中的使用1 语法说明2. 基本用法4 #{…}和${…}

spel获取自定义注解参数值

1.注解类

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();}

2.注解使用

@override@stockwarncollect(customerid = "#customerid", source = "#source", pagetype = "2")public map<string, object> validatecarts(long customerid, t<long> urlectedids, short source, jsonarray couponinfo){  // 省略}

3.aop中处理

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在注解中的使用

spel(spring expression language),即spring表达式语言,是比jsp的el更强大的一种表达式语言。为什么要总结spel,因为它可以在运行时查询和操作数据,尤其是数组列表型数据,因此可以缩减代码量,优化代码结构。个人认为很有用。

1 语法说明

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}’}

2. 基本用法

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 #{…}和${…}

#{…} 用于执行spel表达式,并将内容赋值给属性${…} 主要用于加载外部属性文件中的值#{…} 和${…} 可以混合使用,但是必须#{}外面,${}在里面

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 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图