zoukankan      html  css  js  c++  java
  • 自定义注解使用SPEL表达式记录日志

    一、SPEL表达式

    SPEL(Spring Expression Language)即Spring表达式语言,它是一种类似jsp的EL表达式,但是又比后者更强大的表达式语言。

    例如,经常使用的@Value注解,比如:

    @Value("${saas.baseUrl}")
    private String baseUrl;

    其中参数可以为常量字符串,如:@Value("https://a.valueonline.cn/")

    也可以为#{},在大括号类可以为bena的属性、环境变量,

    也可以为${},这时候在大括号类里面的properties资源文件的配置项,如:@Value("${saas.baseUrl}")

    二、自定义注解,

    我们的目的是需要记录操作的日志,需要具体到某个业务,所以业务的id为动态变化的,如果在每个业务代码里面加入日志会使得业务代码变得更为复杂,所以我们需要自定义注解并且配合使用SPEL表达式

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface IrLog {
    
        /**
         * 模块名称
         */
        ModuleType moduleType();
    
        /**
         * 关联业务主键
         */
        String businessId() default "";
    
        /**
         * 日志内容
         */
        String content() default "";
    
        enum ModuleType {
            BASE_INFO("基本信息", "01"),
    
            LAW_FILE("相关文件", "02"),
    
            ;
    
            private final String moduleName;
    
            private final String moduleValue;
    
            ModuleType(String moduleName, String moduleValue) {
                this.moduleName = moduleName;
                this.moduleValue = moduleValue;
            }
    
            public String getModuleName() {
                return moduleName;
            }
    
            public String getModuleValue() {
                return moduleValue;
            }
        }
    }
    

     三、日志切面类

    @Aspect
    @Component
    public class IrLogAspect  {
    
        private static Logger logger = LoggerFactory.getLogger(IrLogAspect.class);
    
        private final ExpressionParser expressionParser = new SpelExpressionParser();
    
        private DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
    
    
    
    
        @Around("@annotation(log)")
        public Object invoked(ProceedingJoinPoint joinPoint, IrLog log) throws Throwable {
            String businessId = log.businessId();
            String moduleValue = log.moduleType().getModuleValue();
            String content = log.content();
            Log logDto = new Log();
    
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method method = methodSignature.getMethod();
            String[] paramNames = nameDiscoverer.getParameterNames(method);
    
            Expression expression = expressionParser.parseExpression(businessId);
            EvaluationContext context = new StandardEvaluationContext();
            Object[] args = joinPoint.getArgs();
            for (int i = 0 ; i < args.length ; i++) {
                context.setVariable(paramNames[i], args[i]);
            }
    
            String parseBusinessId = expression.getValue(context, String.class);
    
    
    //            logger.info("businessId: {}, moduleValue: {}, dbTime: {}", parseBusinessId, moduleValue, dbTime);
            
    
            return joinPoint.proceed();
        }
    
    }

    使用:

       @PostMapping("/issueRegulations")
        @IrLog(moduleType = IrLog.ModuleType.PUBLISH, businessId = "#regulationsId")
        public void issueRegulations(String regulationsId) {
            
        }
  • 相关阅读:
    委托理解
    WebForm与MVC模式优缺点
    关系型数据库与NOSQL
    抽象类与接口
    Asp.net中的状态保持方案
    数据库[约束]笔记
    xml文件操作
    String、Path、File、Directroy 常用方法总结
    面向对象5个基本设计原则
    面向对象分析与设计
  • 原文地址:https://www.cnblogs.com/LiuFqiang/p/15785375.html
Copyright © 2011-2022 走看看