博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring aop通过注解实现日志记录
阅读量:5878 次
发布时间:2019-06-19

本文共 3988 字,大约阅读时间需要 13 分钟。

首先是几个概念:连接点(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;@Servicepublic 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@Componentpublic 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 //表示启用AOPpublic 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。详细的可以下去再了解

 

转载于:https://www.cnblogs.com/duanjt/p/9927981.html

你可能感兴趣的文章
[翻译]Protocol Buffer 基础: C++
查看>>
runloop与线程的关系
查看>>
[Bzoj2246]迷宫探险(概率+DP)
查看>>
[译] 感受 4px 基线网格带来的便利
查看>>
oracle常用函数
查看>>
MYBATIS
查看>>
详解消息队列的设计与使用
查看>>
iOS 项目优化
查看>>
筛选出sql 查询结果中 不包含某个字符
查看>>
8进制与16进制
查看>>
使用Sqoop从mysql向hdfs或者hive导入数据时出现的一些错误
查看>>
mybatis:Invalid bound statement (not found)
查看>>
电脑中毒的现象
查看>>
django表单操作之django.forms
查看>>
webSocket vnc rfb
查看>>
列表推导式 生成器表达式
查看>>
控制子窗口的高度
查看>>
Linux 防火墙iptables命令详解
查看>>
打造笔记本电脑基地重庆要当全球“老大”
查看>>
处理 Oracle SQL in 超过1000 的解决方案
查看>>