zoukankan      html  css  js  c++  java
  • 使用Spring Aop自定义注解实现自动记录日志

    百度加自己琢磨,以下亲测有效,所以写下来记录,也方便自己回顾浏览加深印象之类,有什么问题可以评论一起解决,不完整之处也请大佬指正,一起进步哈哈
    (1)首先配置文件:

    <!-- 声明自动为spring容器中配置@aspectj切面的bean创建代理 ,织入切面 -->
        <aop:aspectj-autoproxy />
        <!-- 开启注解扫描 -->
        <context:component-scan base-package="com.ky.zhjd.**"/>
        <!-- 为true说明代理基于类被创建(默认false,基于接口被创建) -->
        <aop:config proxy-target-class="true"></aop:config>

    (2)创建一个自定义注解类

    注意创建时选Annotation,类名我叫ArchivesLog(日志档案的意思)。

    ArchivesLog.java内容:

    package com.ky.zhjd.common.log;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    /**
     * 
     * 自定义注解类
     * @author ddz
     *
     */
    @Target({ElementType.PARAMETER, ElementType.METHOD})  
    @Retention(RetentionPolicy.RUNTIME)  
    @Documented  
    public @interface ArchivesLog {
    
        /** 要执行的操作类型比如:添加操作 **/  
        public String operationType() default "";  
    
        /** 要执行的操作名称比如:添加一条用户数据 **/  
        public String operationName() default ""; 
        
    }

    (3)新建一个切面类,我叫LogAspect.java

    package com.ky.zhjd.common.log;
    
    import java.lang.reflect.Method;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * 切面类
     * 
     * @author ddz
     *
     */
    @Aspect
    @Component("logAspect")
    public class LogAspect {
    
        private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
    
        // 配置织入点
        @Pointcut("@annotation(ArchivesLog)")
        public void logPointCut() {
        }
    
        /**
         * 前置通知 用于拦截操作,在方法返回后执行
         * 
         * @param joinPoint 切点
         */
        @AfterReturning(pointcut = "logPointCut()")
        public void doBefore(JoinPoint joinPoint) {
            handleLog(joinPoint, null);
        }
    
        /**
         * 拦截异常操作,有异常时执行
         * 
         * @param joinPoint
         * @param e
         */
        @AfterThrowing(value = "logPointCut()", throwing = "e")
        public void doAfter(JoinPoint joinPoint, Exception e) {
            handleLog(joinPoint, e);
        }
    
        private void handleLog(JoinPoint joinPoint, Exception e) {
            try {
                // 获得注解
                ArchivesLog controllerLog = getAnnotationLog(joinPoint);
                System.out.println("---------------自定义注解:" + controllerLog);
                if (controllerLog == null) {
                    return;
                }
                // 获得方法名称
                String className = joinPoint.getTarget().getClass().getName();
                String methodName = joinPoint.getSignature().getName();
                String type = controllerLog.operationType();
                String name = controllerLog.operationName();
                // 打印日志  这里可以进行插入数据库操作
                log.info(">>>>>>>>>>>>>操作类型:", type);
                log.info(">>>>>>>>>>>>>操作名称:", name);
                log.info(">>>>>>>>>>>>>类名:", className);
                log.info(">>>>>>>>>>>>>方法名:", methodName);
            } catch (Exception exp) {
                // 记录本地异常日志
                log.error("==前置通知异常==");
                log.error("异常信息:", exp.getMessage());
                exp.printStackTrace();
            }
        }
    
        /**
         * 是否存在注解,如果存在就获取
         */
        private static ArchivesLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            if (method != null) {
                // 拿到自定义注解中的信息
                return method.getAnnotation(ArchivesLog.class);
            }
            return null;
        }
    }

    (4)在方法上使用注解 , 然后调用该方法

    @ArchivesLog(operationType="查询操作",operationName="查询一条用户详情")
        @RequestMapping(value = "/findByid", produces={"application/json;charset=UTF-8"})
        public @ResponseBody BaseResult<Object> findByid(String id) {
            String s="11";
            BaseResult<Object> r=userService.findById(s);
            System.out.println(r+">>>>>>>>>>");
        return r;
        
        }

    ok 上效果:

     有什么不完善的地方欢迎指出,一起学习

  • 相关阅读:
    pytest简介
    python @property的用法及含义全面解析
    python的各种推导式(列表推导式、字典推导式、集合推导式)
    python--random库基本介绍
    整理一下python中with的用法
    Python之路:进程、线程
    Python代码风格的良好养成
    Ubuntu 部署Python开发环境
    Python面向对象编程
    Python文件操作
  • 原文地址:https://www.cnblogs.com/zdd-/p/10185100.html
Copyright © 2011-2022 走看看