广告
返回顶部
首页 > 资讯 > 精选 >怎么用Spring的spel获取自定义注解参数值
  • 183
分享到

怎么用Spring的spel获取自定义注解参数值

2023-06-29 04:06:39 183人浏览 安东尼
摘要

这篇文章主要介绍了怎么用spring的spel获取自定义注解参数值的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Spring的spel获取自定义注解参数值文章都会有所收获,下面我们一起来看看吧。spel获

这篇文章主要介绍了怎么用spring的spel获取自定义注解参数值的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Spring的spel获取自定义注解参数值文章都会有所收获,下面我们一起来看看吧。

spel获取自定义注解参数值

1.注解类

package com.xxx.mall.order.service.component; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})@Documentedpublic @interface StockWarnCollect {         String customerId();         String source();         String pageType();}

2.注解使用

@Override@StockWarnCollect(customerId = "#customerId", source = "#source", pageType = "2")public Map<String, Object> validateCarts(Long customerId, Set<Long> userSelectedIds, 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.ExpressionParser;import org.springframework.expression.spel.standard.SpelExpressionParser;import org.springframework.expression.spel.support.StandardEvaluationContext;import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Aspect@Component@Slf4jpublic class StockWarnCollectAop {     @Pointcut(value = "@annotation(com.xxx.mall.order.service.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、来源解析        ExpressionParser parser = new SpelExpressionParser();        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.setVariable(params[len], args[len]);        }        Expression expression = parser.parseExpression(customerIdSpel);        Long customerId = expression.getValue(context, Long.class);         expression = parser.parseExpression(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) {             } else {    // 未知错误                        }             throw e;        }         try {            if (result != null) {                        }        } catch (Exception e) {            log.error("collectStockWarn process error, errorMsg:{}", ExceptionUtils.getStackTrace(e));        }         return result;     }         private Method getTargetMethod(ProceedingJoinPoint pjp) throws NoSuchMethodException {        Signature signature = pjp.getSignature();        MethodSignature methodSignature = (MethodSignature)signature;        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 , ge

  • 逻辑运算符:and , or , not , |

  • if-else 运算符(类似三目运算符):?:(temary), ?:(Elvis)

  • 正则表达式:#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}

2. 基本用法

SpEL有三种用法:

是在注解@Value中;

在XML配置中;

代码块中使用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) {         //创建ExpressionParser解析表达式        ExpressionParser parser = new SpelExpressionParser();        //表达式放置        Expression exp = parser.parseExpression("表达式");        //执行表达式,默认容器是spring本身的容器:ApplicationContext        Object value = exp.getValue();                        //创建一个虚拟的容器EvaluationContext        StandardEvaluationContext ctx = new StandardEvaluationContext();        //向容器内添加bean        BeanA beanA = new BeanA();        ctx.setVariable("bean_id", beanA);                //setRootObject并非必须;一个EvaluationContext只能有一个RootObject,引用它的属性时,可以不加前缀        ctx.setRootObject(XXX);                //getValue有参数ctx,从新的容器中根据SpEL表达式获取所需的值        Object value = exp.getValue(ctx);    }}

4 #{&hellip;}和${&hellip;}

  • #{&hellip;} 用于执行SpEl表达式,并将内容赋值给属性

  • ${&hellip;} 主要用于加载外部属性文件中的值

  • #{&hellip;} 和${&hellip;} 可以混合使用,但是必须#{}外面,${}在里面

4.1 ${&hellip;}用法 

{}里面的内容必须符合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 #{&hellip;}用法 

这里只演示简单用法

    // SpEL:调用字符串Hello World的concat方法    @Value("#{'Hello World'.concat('!')}")    private String helloWorld;     // SpEL: 调用字符串的getBytes方法,然后调用length属性    @Value("#{'Hello World'.bytes.length}")    private String helloWorldbytes;

4.3 ${&hellip;}和#{&hellip;}混合使用 

${...}和#{...}可以混合使用,如下文代码执行顺序:通过${server.name}从属性文件中获取值并进行替换,然后就变成了 执行SpEL表达式{&lsquo;server1,server2,server3&rsquo;.split(&lsquo;,&rsquo;)}。

// SpEL: 传入一个字符串,根据","切分后插入列表中, #{}和${}配置使用(注意单引号,注意不能反过来${}在外面,#{}在里面)    @Value("#{'${server.name}'.split(',')}")    private List<String> servers;

在上文中在#{}外面,${}在里面可以执行成功,那么反过来是否可以呢${}在外面,#{}在里面,如代码

// SpEL: 注意不能反过来${}在外面,#{}在里面,这个会执行失败    @Value("${#{'HelloWorld'.concat('_')}}")    private List<String> servers2;

答案是不能。因为spring执行${}是时机要早于#{}。在本例中,Spring会尝试从属性中查找#{&lsquo;HelloWorld&rsquo;.concat(&lsquo;_&rsquo;)},那么肯定找不到,由上文已知如果找不到,然后报错。所以${}在外面,#{}在里面是非法操作 

关于“怎么用Spring的spel获取自定义注解参数值”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“怎么用Spring的spel获取自定义注解参数值”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: 怎么用Spring的spel获取自定义注解参数值

本文链接: https://www.lsjlt.com/news/322750.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么用Spring的spel获取自定义注解参数值
    这篇文章主要介绍了怎么用Spring的spel获取自定义注解参数值的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Spring的spel获取自定义注解参数值文章都会有所收获,下面我们一起来看看吧。spel获...
    99+
    2023-06-29
  • Spring spel获取自定义注解参数值方式
    目录spel获取自定义注解参数值1.注解类2.注解使用3.aop中处理 spel在注解中的使用1 语法说明2. 基本用法4 #{…}和${…}s...
    99+
    2022-11-13
  • 怎么自定义@RequestBody注解获取JSON数据
    这篇文章主要介绍“怎么自定义@RequestBody注解获取JSON数据”,在日常操作中,相信很多人在怎么自定义@RequestBody注解获取JSON数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么自...
    99+
    2023-07-06
  • Java注解怎么获取请求参数值
    在Java中,可以使用反射来获取方法中的请求参数值。以下是一个示例代码:```javaimport java.lang.annota...
    99+
    2023-09-27
    Java
  • java怎么自定义注解做参数校验
    在Java中,可以使用自定义注解来进行参数校验。以下是一个简单的示例: import java.lang.annotation.El...
    99+
    2023-10-26
    java
  • SpringMVC中的参数怎么利用注解获取
    SpringMVC中的参数怎么利用注解获取?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。SpringMVC可以通过RequestParam注解来映射获得参数,具...
    99+
    2023-05-31
    springmvc
  • 怎么理解PHP常量的定义与值的获取
    本篇内容介绍了“怎么理解PHP常量的定义与值的获取”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!PHP常量是什么常量和变量相对应,常量简单来...
    99+
    2023-06-25
  • 使用@PathVariable注解怎么让spring支持参数带值功能
    本篇文章给大家分享的是有关使用@PathVariable注解怎么让spring支持参数带值功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。@PathVariable的作用获取...
    99+
    2023-06-06
  • php中怎么利用abs()获取参数的绝对值
    这篇文章给大家分享的是有关php中怎么利用abs()获取参数的绝对值的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。php有什么特点1、执行速度快。2、具有很好的开放性和可扩展性。3、PHP支持多种主流与非主流的数...
    99+
    2023-06-15
  • 怎么通过自定义spring invalidator注解校验数据合法性
    今天小编给大家分享一下怎么通过自定义spring invalidator注解校验数据合法性的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面...
    99+
    2023-07-02
  • 使用自定义注解进行restful请求参数的校验方式
    目录自定义注解进行restful请求参数的校验1、首先我们使用@interface定义一个注解2、实现注解实现类(和@interface定义的注解在同一个包下)3、在需要校验的对象的...
    99+
    2022-11-12
  • 如何使用Python的pandas库获取DataFrame数据的最小值、最大值以及自定义分位数?
    一、如何使用Python的pandas库获取DataFrame数据的最小值、最大值以及自定义分位数? Pandas是一个非常流行的Python数据处理库,它提供了大量的方法和工具来处理和分析数据。在本...
    99+
    2023-09-29
    pandas python 数据分析
  • Java带参数与带返回值的方法怎么定义和调用
    这篇文章主要介绍“Java带参数与带返回值的方法怎么定义和调用”,在日常操作中,相信很多人在Java带参数与带返回值的方法怎么定义和调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java带参数与带返回值的...
    99+
    2023-06-29
  • Spring中使用自定义ThreadLocal存储导致的坑怎么解决
    这篇文章主要介绍了Spring中使用自定义ThreadLocal存储导致的坑怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring中使用自定义ThreadLocal...
    99+
    2022-10-19
  • Java拦截器以及自定义注解的使用是怎么样的
    Java拦截器以及自定义注解的使用是怎么样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1,设置预处理,设置不需要拦截的请求@Componentpublic cla...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作