返回顶部
首页 > 资讯 > 后端开发 > Python >在@Value注解内使用SPEL自定义函数方式
  • 761
分享到

在@Value注解内使用SPEL自定义函数方式

2024-04-02 19:04:59 761人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录@Value注解内使用SPEL自定义函数自定义注解支持SpEL表达式1.定义日志注解2.定义spel解析工具类3.定义切面类4.方法上使用日志注解@Value注解内使用SPEL自

@Value注解内使用SPEL自定义函数

@Value("#{T(com.cheetah.provider.utils.StringUtil).lower('${cluster.vendor.type}')}")

其中,${cluster.vendor.type}取的application.properties中的配置,com.cheetah.provider.utils.StringUtil#lower是用户自定义函数,

T()运算符的结果是一Class对象,它的真正价值在于它能够访问目标类型的静态方法和常量

自定义注解支持SpEL表达式

利用aop生成用户操作日志

1.定义日志注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
    //普通的操作说明
    String value() default "";
    
    //spel表达式的操作说明
    String spelValue() default "";
}

2.定义spel解析工具类

public class SpelUtil {
    
    private static SpelExpressionParser parser = new SpelExpressionParser();
    
    private static DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
    public static String generateKeyBySpEL(String spELString, ProceedingJoinPoint joinPoint) {
        // 通过joinPoint获取被注解方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 使用spring的DefaultParameterNameDiscoverer获取方法形参名数组
        String[] paramNames = nameDiscoverer.getParameterNames(method);
        // 解析过后的Spring表达式对象
        Expression expression = parser.parseExpression(spELString);
        // spring的表达式上下文对象
        EvaluationContext context = new StandardEvaluationContext();
        // 通过joinPoint获取被注解方法的形参
        Object[] args = joinPoint.getArgs();
        // 给上下文赋值
        for (int i = 0; i < args.length; i++) {
            context.setVariable(paramNames[i], args[i]);
        }
        // 表达式从上下文中计算出实际参数值
        
        return expression.getValue(context).toString();
    }
}

3.定义切面类

@Aspect
@Component
public class SysLogAspect {
    @Autowired
    private LogService logService;
    @Autowired
    private httpservletRequest request;
    @Pointcut("@annotation(com.ztri.common.annotation.SysLog)")
    public void logPointCut() {
    }
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        saveSysLog(point, time);
        return result;
    }
    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log sysLog = new Log();
        sysLog.setTime(time);
        SysLog syslog = method.getAnnotation(SysLog.class);
        if (syslog != null) {
            //注解上的描述
            if (StrUtil.isNotBlank(syslog.value())) {
                sysLog.setOperation(syslog.value());
            }
            if (StrUtil.isNotBlank(syslog.spelValue())) {
                String spelValue = SpelUtil.generateKeyBySpEL(syslog.spelValue(), joinPoint);
                sysLog.setOperation(spelValue);
            }
        }
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        //请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            String params = JSONUtil.tojsonStr(args);
            sysLog.setParams(params);
        } catch (Exception e) {
        }
        //设置IP地址
        sysLog.setIp(ServletUtil.getClientIP(request));
        UserAgent ua = UserAgentUtil.parse(request.getHeader("User-Agent"));
        sysLog.setBrowser(ua.getBrowser().toString());
        //保存系统日志
        logService.create(sysLog);
    }
}

4.方法上使用日志注解

    @apiOperation("高级搜索(包含点击1.热门列表 2.更多跳转页面)")
    @PostMapping("searchData")
    @SysLog(spelValue = "'高级搜索' + #searchVo.keyWord")
    public ResponseEntity<Object> searchData(@RequestBody SearchVo searchVo) throws IOException {
        SearchDto searchDto = searchService.searchData(searchVo);
        return new ResponseEntity<>(searchDto, HttpStatus.OK);
    }
    @ApiOperation("登录授权")
    @PostMapping("/login")
    @SysLog("用户登录")
    public ResponseEntity<Object> login(@Validated(User.Create.class) @RequestBody LoginUser loginUser) {
        return ResponseEntity.ok(authInfo);
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 在@Value注解内使用SPEL自定义函数方式

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

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

猜你喜欢
  • 在@Value注解内使用SPEL自定义函数方式
    目录@Value注解内使用SPEL自定义函数自定义注解支持SpEL表达式1.定义日志注解2.定义spel解析工具类3.定义切面类4.方法上使用日志注解@Value注解内使用SPEL自...
    99+
    2024-04-02
  • Spring spel获取自定义注解参数值方式
    目录spel获取自定义注解参数值1.注解类2.注解使用3.aop中处理 spel在注解中的使用1 语法说明2. 基本用法4 #{…}和${…}s...
    99+
    2024-04-02
  • 使用Springboot自定义注解,支持SPEL表达式
    目录Springboot自定义注解,支持SPEL表达式1.自定义注解2.使用AOP拦截方法,解析注解参数自定义注解结合切面和spel表达式自定义一个注解自定义一个service类,在...
    99+
    2024-04-02
  • 自定义注解+Spel实现分布式锁方式
    目录自定义注解+Spel实现分布式锁依赖RedisLockRegistryConfig自定义注解自定义切面测试类执行结果基于注解的方式实现分布式锁redis分布式锁的实现测试自定义注...
    99+
    2024-04-02
  • 如何使用Springboot自定义注解并支持SPEL表达式
    这篇文章主要介绍了如何使用Springboot自定义注解并支持SPEL表达式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Springboot自定义注解,支持SPEL表达式举...
    99+
    2023-06-29
  • 怎么用Spring的spel获取自定义注解参数值
    这篇文章主要介绍了怎么用Spring的spel获取自定义注解参数值的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Spring的spel获取自定义注解参数值文章都会有所收获,下面我们一起来看看吧。spel获...
    99+
    2023-06-29
  • 支持SpEL表达式的自定义日志注解@SysLog介绍
    目录序言预期思路过程结果序言 之前封装过一个日志注解,打印方法执行信息,功能较为单一不够灵活,近来兴趣来了,想重构下,使其支持表达式语法,以应对灵活的日志打印需求。 该注解是方法层面...
    99+
    2024-04-02
  • MySQL内置函数和自定义函数怎么使用
    这篇“MySQL内置函数和自定义函数怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL内置函数和自定义函数怎么...
    99+
    2023-07-02
  • 使用自定义注解+springAop实现参数非空校验方式
    目录自定义注解+springAop参数非空校验新建注解类@interface ParamsVerify利用springAop来实现切面新建一个切面类使用注解统一校验参数非空1. 待校...
    99+
    2024-04-02
  • 使用Spring自定义实现IOC和依赖注入(注解方式)
    目录大致思路:注解实现方式:xml实现方式:1. 引入相关jar2. 定义注解类ExtService是注解类的, ExtResource是注解属性的3.定义一个借口4. 接口和使用注...
    99+
    2024-04-02
  • Spring Boot 注解方式自定义Endpoint详解
    目录概述准备编写自定义Endpoint配置启动&测试注意Spring Boot 常用endpoint的使用Actuator一些常用 Endpoint如何访问 Actuator...
    99+
    2024-04-02
  • 使用自定义注解实现加解密及脱敏方式
    目录自定义注解实现加解密及脱敏定义自定义注解构造AOP逻辑测试脱敏逻辑自定义一种字符串的加密与解密自定义注解实现加解密及脱敏 定义自定义注解 @Documented @Targe...
    99+
    2024-04-02
  • SpringAOP如何在注解上使用SPEL表达式注入对象
    目录在注解上使用SPEL表达式注入对象场景描述具体案例补充Spring属性注入方式之SPEL表达式在注解上使用SPEL表达式注入对象 场景描述 在平时开发中,我们经常通过定义一些注解...
    99+
    2024-04-02
  • 如何在SQLite中使用自定义函数
    在SQLite中使用自定义函数可以通过以下步骤实现: 创建一个自定义函数: CREATE FUNCTION my_functio...
    99+
    2024-03-14
    SQLite
  • 使用自定义注解进行restful请求参数的校验方式
    目录自定义注解进行restful请求参数的校验1、首先我们使用@interface定义一个注解2、实现注解实现类(和@interface定义的注解在同一个包下)3、在需要校验的对象的...
    99+
    2024-04-02
  • java自定义切面增强方式(关于自定义注解aop)
    目录java自定义切面增强切面、自定义注解的使用AOP简介AOP定义注解简介元素和组成元注解总结java自定义切面增强 写代码时会遇到一些有些重复机械的工作, 这个时候就可以运用切面...
    99+
    2023-05-14
    java自定义切面增强 自定义注解aop java切面
  • mybatis自动扫描和自定义类注解方式
    目录mybatis自动扫描和自定义类注解Spring mybatis自动扫描dao解决方案mybatis自动扫描和自定义类注解 以往都是使用自定义注解实现Dao层mapper.jav...
    99+
    2024-04-02
  • 使用自定义注解实现redisson分布式锁
    目录自定义注解实现redisson分布式锁自定义注解aop解析注解service中使用注解加锁使用redisson分布式锁应用应用场景Redisson管理类分布式锁测试类自定义注解实...
    99+
    2024-04-02
  • 【Java 注解】自定义注解(注解属性与使用)
    文章目录 前言一、自定义注解与元注解1.注解属性类型 二、注解的生命周期以及作用目标1.生命周期2.作用目标 三,简单使用四,注解属性赋值简化 前言 Java注解是一种元数据(m...
    99+
    2023-10-21
    java spring spring boot log4j 经验分享 笔记 后端
  • Java注解怎么自定义使用
    这篇文章主要介绍了Java注解怎么自定义使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java注解怎么自定义使用文章都会有所收获,下面我们一起来看看吧。注解注解基本介绍注解概述:Java 注解(Annota...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作