博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring AOP从入门到放弃之自定义注解收集系统日志
阅读量:6936 次
发布时间:2019-06-27

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

希望的效果为

需求

用户点击了某个界面,请求了后台某个接口。接口请求到后台后,记录请求的数据到数据库中。

实现方式

1、自定义一个注解,被加注解的方法,请求的数据被保存下来

2、定义一个aop 去拦截被注解的方法
3、写一个线程池、执行拦截后的逻辑。也就是保存到数据库中

效果图

这里写图片描述

查看到刚刚请求用户列表界面的执行情况

这里写图片描述

实现步骤

1、自定义注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface SLog {    String value() default "";}

定义一个aop拦截注解

@Aspect@Componentpublic class SLogAspect {
/** * 保存日志到数据库的线程池 */ ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("SLogAspect-Thread-%d").build(); ExecutorService executor = new ThreadPoolExecutor(5,200,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue
(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy()); @Pointcut("@annotation(com.slife.annotation.SLog)") 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; // 获取request HttpServletRequest request = ServletUtils.getHttpServletRequest(); //获取请求的ip String ip = IPUtils.getIpAddr(request); SaveLogTask saveLogTask = new SaveLogTask(point, time, ip); //保存日志到数据库 executor.execute(saveLogTask); return result; }}

线程池执行保存数据到数据库

/** * * @author chen * @date 2017/9/19 * 

* Email 122741482@qq.com *

* Describe: */public class SaveLogTask implements Runnable {

private SlifeLogDao slifeLogDao = ApplicationContextRegister.getBean(SlifeLogDao.class); private ProceedingJoinPoint joinPoint; private long time; private String ip; public SaveLogTask(ProceedingJoinPoint point, long time, String ip) { this.joinPoint = point; this.time = time; this.ip = ip; } @Override public void run() { saveLog(joinPoint, time, ip); } /** * 保存日志 到数据库 * * @param joinPoint * @param time */ private void saveLog(ProceedingJoinPoint joinPoint, long time, String ip) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SlifeLog slifeLog = new SlifeLog(); SLog sLog = method.getAnnotation(SLog.class); if (slifeLog != null) { // 注解上的描述 slifeLog.setMsg(sLog.value()); } // 请求的方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); slifeLog.setSrc(className + "." + methodName + "()"); // 请求的参数 Object[] args = joinPoint.getArgs(); try { String params = JSON.toJSONString(args[0]); slifeLog.setParams(params); } catch (Exception e) { } // 设置IP地址 slifeLog.setIp(ip); // 用户名 ShiroUser currUser = SlifeSysUser.ShiroUser(); if (null == currUser) { if (null != slifeLog.getParams()) { slifeLog.setName(slifeLog.getParams()); slifeLog.setLoginName(slifeLog.getParams()); } else { slifeLog.setName("获取用户信息为空"); slifeLog.setLoginName("获取用户信息为空"); slifeLog.setCreateId(-1L); } } else { slifeLog.setName(currUser.getName()); slifeLog.setLoginName(currUser.getUsername()); } slifeLog.setUseTime(time); // 保存系统日志 slifeLogDao.insert(slifeLog); }}

给需要的方法加注解

@SLog("获取用户列表数据")    @ApiOperation(value = "获取用户列表数据", notes = "获取用户列表:使用约定的DataTable")    @PostMapping(value = "/list")    @ResponseBody    public DataTable
list(@RequestBody DataTable dt, ServletRequest request) { return sysUserService.pageSearch(dt); } @SLog("获取用户列表数据")

简单的一个 记录请求的日志 实现。

说明

这里把保存到数据库的逻辑写到了一个线程池中,主要是不希望记录日志的逻辑影响了用户请求数据接口的逻辑,和性能。

我的官网

我的博客

我的官网

我的CSDN地址
我的简书地址
我的github
我的码云地址
阿里云优惠券

你可能感兴趣的文章
php7 安装扩展
查看>>
【总结整理】数据可视化
查看>>
安装zookeeper
查看>>
FFmpeg-20160422-snapshot-bin
查看>>
C 语言复杂声明
查看>>
IOS 二张图片合并
查看>>
【java】在分页查询结果中对最后的结果集List进行操作add()或remove()操作,报错:java.lang.UnsupportedOperationException...
查看>>
CentOS系统环境下安装MongoDB
查看>>
LeetCode 3. Longest Substring Without Repeating Characters
查看>>
安卓模拟器BlueStacks 安装使用教程(图解)
查看>>
Hadoop YARN学习之Hadoop框架演进历史简述
查看>>
C++中友元类使用场合
查看>>
Laravel5.5的异常捕获和处理
查看>>
large graph挖掘的技术基础
查看>>
Tips_发送请求时添加一个随机数参数,让浏览器每次都重新发请求到服务器
查看>>
检验重复字母代码
查看>>
SQL Server 2012 安装杂谈
查看>>
[训练日志] 7月22-31日
查看>>
Html转义字符列表
查看>>
2、cocos2d-js引擎的安装和新建
查看>>