最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?spel獲取自定義注解參數(shù)值方式

 更新時(shí)間:2022年02月17日 10:11:03   作者:公子  
這篇文章主要介紹了Spring?spel獲取自定義注解參數(shù)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

spel獲取自定義注解參數(shù)值

1.注解類

package com.xxx.mall.order.service.component;?
import java.lang.annotation.*;
?
/**
?* 庫存不足等信息監(jiān)控
?* Created by xdc on 2019/4/16 15:43
?*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface StockWarnCollect {
?
? ? /** 客戶id */
? ? String customerId();
?
? ? /** 來源 */
? ? String source();
?
? ? /** 請(qǐng)求類型 1:詳情頁 2:購物車去結(jié)算 3:提交訂單 */
? ? 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;
 
/**
 * 下單失敗、庫存監(jiān)控
 * Created by xdc on 2019/4/16 15:45
 */
@Aspect
@Component
@Slf4j
public 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);
 
        // 業(yè)務(wù)邏輯處理
        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 {    // 未知錯(cuò)誤
            
            } 
            throw e;
        } 
        try {
            if (result != null) {            
            }
        } catch (Exception e) {
            log.error("collectStockWarn process error, errorMsg:{}", ExceptionUtils.getStackTrace(e));
        } 
        return result; 
    } 
    /**
     * 獲取目標(biāo)方法
     */
    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表達(dá)式語言,是比JSP的EL更強(qiáng)大的一種表達(dá)式語言。為什么要總結(jié)SpEL,因?yàn)樗梢栽谶\(yùn)行時(shí)查詢和操作數(shù)據(jù),尤其是數(shù)組列表型數(shù)據(jù),因此可以縮減代碼量,優(yōu)化代碼結(jié)構(gòu)。個(gè)人認(rèn)為很有用。

1 語法說明

1.1 SpEL 字面量:

  • 整數(shù):#{8}
  • 小數(shù):#{8.8}
  • 科學(xué)計(jì)數(shù)法:#{1e4}
  • String:可以使用單引號(hào)或者雙引號(hào)作為字符串的定界符號(hào)。
  • Boolean:#{true}

1.2 SpEL引用bean , 屬性和方法:

  • 引用其他對(duì)象:#{car}
  • 引用其他對(duì)象的屬性:#{car.brand}
  • 調(diào)用其它方法 , 還可以鏈?zhǔn)讲僮鳎?{car.toString()}
  • 調(diào)用靜態(tài)方法靜態(tài)屬性:#{T(java.lang.Math).PI}

1.3 SpEL支持的運(yùn)算符號(hào):

  • 算術(shù)運(yùn)算符:+,-,*,/,%,^(加號(hào)還可以用作字符串連接)
  • 比較運(yùn)算符:< , > , == , >= , <= , lt , gt , eg , le , ge
  • 邏輯運(yùn)算符:and , or , not , |
  • if-else 運(yùn)算符(類似三目運(yùn)算符):?:(temary), ?:(Elvis)
  • 正則表達(dá)式:#{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能修飾成員變量和方法形參
? ? //#{}內(nèi)就是表達(dá)式的內(nèi)容
? ? @Value("#{表達(dá)式}")
? ? public String arg;

2.2 <bean>配置

<bean id="xxx" class="com.java.XXXXX.xx">
? ? <!-- 同@Value,#{}內(nèi)是表達(dá)式的值,可放在property或constructor-arg內(nèi) -->
? ? <property name="arg" value="#{表達(dá)式}">
</bean>

2.3 代碼塊中使用

public class SpELTest {?
? ? public static void main(String[] args) {
?
? ? ? ? //創(chuàng)建ExpressionParser解析表達(dá)式
? ? ? ? ExpressionParser parser = new SpelExpressionParser();
? ? ? ? //表達(dá)式放置
? ? ? ? Expression exp = parser.parseExpression("表達(dá)式");
? ? ? ? //執(zhí)行表達(dá)式,默認(rèn)容器是spring本身的容器:ApplicationContext
? ? ? ? Object value = exp.getValue();
? ? ? ??
? ? ? ? /**如果使用其他的容器,則用下面的方法*/
? ? ? ? //創(chuàng)建一個(gè)虛擬的容器EvaluationContext
? ? ? ? StandardEvaluationContext ctx = new StandardEvaluationContext();
? ? ? ? //向容器內(nèi)添加bean
? ? ? ? BeanA beanA = new BeanA();
? ? ? ? ctx.setVariable("bean_id", beanA);
? ? ? ??
? ? ? ? //setRootObject并非必須;一個(gè)EvaluationContext只能有一個(gè)RootObject,引用它的屬性時(shí),可以不加前綴
? ? ? ? ctx.setRootObject(XXX);
? ? ? ??
? ? ? ? //getValue有參數(shù)ctx,從新的容器中根據(jù)SpEL表達(dá)式獲取所需的值
? ? ? ? Object value = exp.getValue(ctx);
? ? }
}

4 #{…}和${…}

  • #{…} 用于執(zhí)行SpEl表達(dá)式,并將內(nèi)容賦值給屬性
  • ${…} 主要用于加載外部屬性文件中的值
  • #{…} 和${…} 可以混合使用,但是必須#{}外面,${}在里面

4.1 ${…}用法 

{}里面的內(nèi)容必須符合SpEL表達(dá)式,通過@Value(“${spelDefault.value}”)可以獲取屬性文件中對(duì)應(yīng)的值,但是如果屬性文件中沒有這個(gè)屬性,則會(huì)報(bào)錯(cuò)。可以通過賦予默認(rèn)值解決這個(gè)問題,如@Value("${spelDefault.value:127.0.0.1}")

// 如果屬性文件沒有spelDefault.value,則會(huì)報(bào)錯(cuò)
? ? // ?@Value("${spelDefault.value}")
? ? // ?private String spelDefault2;
?
? ? // 使用default.value設(shè)置值,如果不存在則使用默認(rèn)值
? ? @Value("${spelDefault.value:127.0.0.1}")
? ? private String spelDefault;

4.2 #{…}用法 

這里只演示簡單用法

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

4.3 ${…}和#{…}混合使用 

${...}和#{...}可以混合使用,如下文代碼執(zhí)行順序:通過${server.name}從屬性文件中獲取值并進(jìn)行替換,然后就變成了 執(zhí)行SpEL表達(dá)式{‘server1,server2,server3’.split(‘,’)}。

// SpEL: 傳入一個(gè)字符串,根據(jù)","切分后插入列表中, #{}和${}配置使用(注意單引號(hào),注意不能反過來${}在外面,#{}在里面)
? ? @Value("#{'${server.name}'.split(',')}")
? ? private List<String> servers;

在上文中在#{}外面,${}在里面可以執(zhí)行成功,那么反過來是否可以呢${}在外面,#{}在里面,如代碼

// SpEL: 注意不能反過來${}在外面,#{}在里面,這個(gè)會(huì)執(zhí)行失敗
? ? @Value("${#{'HelloWorld'.concat('_')}}")
? ? private List<String> servers2;

答案是不能。因?yàn)閟pring執(zhí)行${}是時(shí)機(jī)要早于#{}。在本例中,Spring會(huì)嘗試從屬性中查找#{‘HelloWorld’.concat(‘_’)},那么肯定找不到,由上文已知如果找不到,然后報(bào)錯(cuò)。所以${}在外面,#{}在里面是非法操作 

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java復(fù)制(拷貝)數(shù)組的五種方法匯總

    Java復(fù)制(拷貝)數(shù)組的五種方法匯總

    java基礎(chǔ)在Java中我們經(jīng)常需要復(fù)制一個(gè)數(shù)組,下面這篇文章主要給大家介紹了關(guān)于Java復(fù)制(拷貝)數(shù)組的五種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • 教你怎么用IDEA快速生成注釋文檔

    教你怎么用IDEA快速生成注釋文檔

    這篇文章主要介紹了教你怎么用IDEA快速生成注釋文檔,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)IDEA操作的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Eclipse將Maven項(xiàng)目打成jar包的方法

    Eclipse將Maven項(xiàng)目打成jar包的方法

    這篇文章主要介紹了Eclipse將Maven項(xiàng)目打成jar包的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2007-09-09
  • Java實(shí)現(xiàn)音頻轉(zhuǎn)文本的示例代碼(語音識(shí)別)

    Java實(shí)現(xiàn)音頻轉(zhuǎn)文本的示例代碼(語音識(shí)別)

    Java中實(shí)現(xiàn)音頻轉(zhuǎn)文本通常涉及使用專門的語音識(shí)別服務(wù),本文主要介紹了Java實(shí)現(xiàn)音頻轉(zhuǎn)文本的示例代碼(語音識(shí)別),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Spring?Boot存在路徑遍歷漏洞CVE-2021-22118的問題解析

    Spring?Boot存在路徑遍歷漏洞CVE-2021-22118的問題解析

    CVE-2021-22118?是一個(gè)在?Spring?Boot?中發(fā)現(xiàn)的漏洞,該漏洞關(guān)系到?Spring?Boot?的開發(fā)者工具(Devtools)中的遠(yuǎn)程更新(Remote?Update)功能,這篇文章主要介紹了Spring?Boot存在路徑遍歷漏洞CVE-2021-22118,需要的朋友可以參考下
    2023-09-09
  • Java身份證號(hào)碼校驗(yàn)工具類詳解

    Java身份證號(hào)碼校驗(yàn)工具類詳解

    這篇文章主要為大家詳細(xì)介紹了Java身份證號(hào)碼校驗(yàn)工具類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • SpringBoot2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解

    SpringBoot2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解

    這篇文章主要介紹了SpringBoot 2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • JAVA三種異常處理機(jī)制的具體使用

    JAVA三種異常處理機(jī)制的具體使用

    異常是程序在編譯或執(zhí)行的過程中可能出現(xiàn)的問題,本文主要介紹了JAVA三種異常處理機(jī)制的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • 深入理解Java基礎(chǔ)之try-with-resource語法糖

    深入理解Java基礎(chǔ)之try-with-resource語法糖

    這篇文章主要介紹了深入理解Java基礎(chǔ)之try-with-resource語法糖,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • JAVA8獨(dú)有的map遍歷方式(非常好用)

    JAVA8獨(dú)有的map遍歷方式(非常好用)

    這篇文章主要介紹了JAVA8獨(dú)有的map遍歷方式(非常好用),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評(píng)論

镇巴县| 安图县| 江永县| 肇东市| 德格县| 毕节市| 龙陵县| 平顶山市| 北川| 翁牛特旗| 集贤县| 洪洞县| 靖州| 慈利县| 遂川县| 综艺| 兴义市| 延吉市| 康平县| 山西省| 瓦房店市| 巴东县| 凯里市| 塘沽区| 古丈县| 安新县| 青田县| 离岛区| 垦利县| 武汉市| 恩施市| 新津县| 乌苏市| 五河县| 隆化县| 东乡| 乌拉特前旗| 鄂托克前旗| 武邑县| 清新县| 马边|