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

 更新时间:2022年02月17日 10:53:41   作者:daijiguo  
这篇文章主要介绍了在@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 {
    /**
     * 用于SpEL表达式解析.
     */
    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]);
        }
        // 表达式从上下文中计算出实际参数值
        /*如:
            @annotation(key="#student.name")
             method(Student student)
             那么就可以解析出方法形参的某属性值,return “xiaoming”;
          */
        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);
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot Entity中枚举类型详细使用介绍

    SpringBoot Entity中枚举类型详细使用介绍

    本文介绍SpringBoot如何在Entity(DAO)中使用枚举类型。(本文使用MyBatis-Plus)。在实际开发中,经常会遇到表示类型或者状态的情况,比如:有三种支付方式:微信、支付宝、银联。本文介绍如何这种场景的方案对比,并用实例来介绍如何用枚举这种最优雅的来表示
    2022-10-10
  • 关于Java中数组切片的几种方法(获取数组元素)

    关于Java中数组切片的几种方法(获取数组元素)

    这篇文章主要介绍了关于Java中数组切片的几种方法(获取数组元素),切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制,需要的朋友可以参考下
    2023-05-05
  • Mybatis以main方法形式调用dao层执行代码实例

    Mybatis以main方法形式调用dao层执行代码实例

    这篇文章主要介绍了Mybatis以main方法形式调用dao层执行代码实例,MyBatis 是一款优秀的持久层框架,MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,需要的朋友可以参考下
    2023-08-08
  • Mybatis-plus配置多数据源,连接多数据库方式

    Mybatis-plus配置多数据源,连接多数据库方式

    这篇文章主要介绍了Mybatis-plus配置多数据源,连接多数据库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • SpringBoot使用ExceptionHandler做异常处理

    SpringBoot使用ExceptionHandler做异常处理

    这篇文章主要介绍了SpringBoot使用ExceptionHandler做异常处理,这篇文章通过多种方法案例来介绍该项技术的使用,需要的朋友可以参考下
    2021-06-06
  • Spring中@PathVariable和@RequestParam注解的用法区别

    Spring中@PathVariable和@RequestParam注解的用法区别

    这篇文章主要介绍了Spring中@PathVariable和@RequestParam注解的用法区别,@PathVariable 是 Spring 框架中的一个注解,用于将 URL 中的变量绑定到方法的参数上,它通常用于处理 RESTful 风格的请求,从 URL 中提取参数值,并将其传递给方法进行处理,需要的朋友可以参考下
    2024-01-01
  • Java集合与数组区别简介及相互转换实例

    Java集合与数组区别简介及相互转换实例

    这篇文章主要介绍了Java集合与数组区别简介及相互转换实例,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • mybatis相同的sql查询第二次查不出结果问题

    mybatis相同的sql查询第二次查不出结果问题

    这篇文章主要介绍了mybatis相同的sql查询第二次查不出结果问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • eclipse+jdk安装以及会遇到的问题及解决方法

    eclipse+jdk安装以及会遇到的问题及解决方法

    这篇文章主要介绍了eclipse+jdk安装以及会遇到的问题+解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 简单了解Spring IoC相关概念原理

    简单了解Spring IoC相关概念原理

    这篇文章主要介绍了简单了解Spring IoC相关概念原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论