• spring aop通过注解实现日志记录


    首先是几个概念:连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、切面(Aspect)

    另外也要使用到注解。

    需求:通过注解定义LogEnable。然后程序运行能够识别定义了LogEnable注解的方法记录日志。

    1.定义注解 

    package cn.duanjt.util;
    
    import java.lang.annotation.*;
    
    /**
     * 记录日志的注解类
     * @author 段江涛
     * @date 2018-11-08
     */
    @Target(ElementType.METHOD)//表示用于标识方法
    @Retention(RetentionPolicy.RUNTIME)//表示运行时保留
    public @interface LogEnable {
        /**
         * 主要是标志日志的描述信息
         * @return
         */
        String note() default "";
    }

    2.定义需要监听的类和方法

    package cn.duanjt.service;
    
    import org.springframework.stereotype.Service;
    
    import cn.duanjt.Pojo.Student;
    import cn.duanjt.util.LogEnable;
    
    @Service
    public class StudentService {
        //定义注解,然后描述当前方法的作用
        @LogEnable(note="获取学生信息")
        public Student getStudent(int id) {
            if (id == 0) {
                throw new RuntimeException("编码不能为0");
            }
            Student stu = new Student();
            stu.setId(id);
            stu.setName("zhangsan");
            stu.setAddr("重庆");
            return stu;
        }
    
        //未定义注解,将不会被监听
        public int getId(int id) {
            return id + 1;
        }
    }

    3.定义切面,记录日志

    package cn.duanjt.util;
    
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogHelper {
        // 没有单独定义切点,直接在环绕方法里面处理[包cn.duanjt.service下面的所有类下面的所有方法,同时包含LogEnable注解的将被监听]
        @Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)")
        public Object around(ProceedingJoinPoint point) {
            MethodSignature signature = (MethodSignature) point.getSignature();
            long time = System.currentTimeMillis();                        //记录开始时间
            String className = point.getTarget().getClass().getName();    // 类名
            String method = className + "." + signature.getName();        //方法名
            Object[] args = point.getArgs();                            // 参数
            
            LogEnable logEnable= signature.getMethod().getAnnotation(LogEnable.class);
            String logNote=logEnable.note();                            //日志信息
            try {
                Object result = point.proceed();
                System.out.println("方法名:" + method);
                System.out.println("参数:" + StringUtils.join(args));
                System.out.println("返回值:" + result.toString());
                System.out.println("日志功能:" + logNote);
                System.out.println("耗时:" + (System.currentTimeMillis() - time) + "毫秒");
                System.out.println("-----------------------");
                return result;
            } catch (Exception e) {
                System.out.println("方法名1:" + method);
                System.out.println("参数:" + StringUtils.join(args));
                System.out.println("日志功能:" + logNote);
                System.out.println("异常信息:" + e.getMessage());
                System.out.println("耗时:" + (System.currentTimeMillis() - time) + "毫秒");
                System.out.println("-----------------------");
                return null;
            } catch (Throwable e) {
                return null;
            }
    
        }
    }

    4.在主程序上要加上注解@EnableAspectJAutoProxy。我这里使用的是springboot,如下:

    package cn.duanjt;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    @SpringBootApplication
    @ComponentScan("cn.duanjt")
    @EnableAspectJAutoProxy //表示启用AOP
    public class ServerDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ServerDemoApplication.class, args);
        }
    }

    最后,运行结果如下:

    方法名:cn.duanjt.service.StudentService.getStudent
    参数:1
    返回值:Student [id=1, name=zhangsan, addr=重庆]
    日志功能:获取学生信息
    耗时:0毫秒
    -----------------------

    注意:

    1. @EnableAspectJAutoProxy用于开启全局的AOP

    2. LogHelper类上面的@Aspect和@Component是必须的,前者用于标注是切面,后者用于将对象注入到spring容器

    3. 切面表达式@Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)").一定需要execution。详细的可以下去再了解

  • 相关阅读:
    Git 版本更新(Windows下)
    Qt Quick 构建 Android app
    Android Studio更新到3.6.0 Gradle报错No cached version of com.android.tools.build:aapt2:3.2.0-alpha16-4748712 available for of...
    在自定义类中使用setMouseCallBack
    关于Qt 状态机
    C++ 新特性 移动构造函数和移动赋值
    关于Qt MetaObject connectSlotsByName
    Prototype 设计模式在框架中的应用
    关于设计模式
    如何提高Qt工程的编译速度
  • 原文地址:https://www.cnblogs.com/duanjt/p/9927981.html
Copyright © 2020-2023  润新知