SpringBoot之日志注解和缓存优化

日志注解:

关于SpringBoot中的日志处理,在之前的文章中页写过:

点击进入

这次通过注解+Aop的方式来实现日志的输出;

首先需要定义一个注解类:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String module() default ""; //模块名
String operation() default ""; //操作名
}

然后定义切点:

//定义切点
@Pointcut("@annotation(com.xbhog.springbootvueblog.common.aop.LogAnnotation)")
public void logPointCut() {
}

白话文就是,注解所到之处都是切点;比较专业的解释的话可以自行百度或者Google;

有了切点,那么我们需要实现通知事件,这里采用了环绕通知,也就是前后都会增强。

//环绕  处理流之前 和之后
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
recordLog(point, time);
return result;
}

point.proceed()就是注解下所需要执行的方法;类似于下面代码段:

@LogAnnotation(module = "listArticle", operation = "显示主页展示数据")
public Result listArticle(@RequestBody PageParams pageParams) {
return articleService.listArticle(pageParams);
}

然后我们需要设置日志输出的信息(recordLog),这里我们通过反射来获得相应的类名和方法名以及其他信息等。

private void recordLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
log.info("=====================log start================================");
log.info("module:{}",logAnnotation.module());
log.info("operation:{}",logAnnotation.operation()); //请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.info("request method:{}",className + "." + methodName + "()"); //请求的参数
Object[] args = joinPoint.getArgs();
String params = JSON.toJSONString(args[0]);
log.info("params:{}",params); //获取request 设置IP地址
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
log.info("ip:{}", IpUtils.getIpAddr(request)); log.info("excute time : {} ms",time);
log.info("=====================log end================================");
}

这样切点和切面已经完成了,使用的时候只需要在方法的上面直接加注解就可以获得对应的方法的日志信息,这样在上线的时候遇到报错直接就可以定位到了。

缓存的优化:

这个是在具体的项目中实现的,流程大体跟上面的实现类似,使用的也是注解实现的。

为什么需要使用缓存来提高网页内容的访问效率,因为内存的读取比硬盘读取的速度快的多的多,这样对用户的体验比较好,但是不是所有的数据都得放到缓存中,因为内存比磁盘贵的多,所以对哪些数据进行缓存能使得用户和服务器均衡也需要一定的经验。

Cache注解:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cache {
long expire() default 1 * 60 * 1000; //存活时间
String name() default ""; //缓存的名字
}

这里设置了数据的存活时间和名字,使得数据在一定的时间里可以在内存中读取数据。

接下来看下缓存的AOP实现:

直接来看下环绕通知的处理流程:

根据图示,首先获取类名和调用的方法名,然后设置两个数组,一个保存参数类型一个保存参数。

遍历参数,将其转换成字符串,然后判断字符串参数(params)为不为空,不为空的话,加密当前字符串参数,将当前的加密的密码保存到Redis中,每次进入该切面的时候,需要判断RedisValue是否为空,如果为空的话,那么需要执行注解下面的方法,如果不为空的话,直接从Redis中直接读取数据显示到前台上。

通过日志Aop与缓存Aop的功能操作,实现效果如下:

结束:

如果你看到这里或者正好对你有所帮助,希望能点个或者感谢;

有错误的地方,欢迎在评论指出,作者看到会进行修改。

最新文章

  1. Unicode转义(\uXXXX)的编码和解码
  2. 第四篇:白话tornado源码之褪去模板外衣的前戏
  3. 转载-------makefile 使用总结
  4. Ogre代码学习之1——Ogre中地形lod的基础:deltaHeight的计算
  5. java单例,懒汉&饿汉
  6. PHP Error 和 Logging 函数
  7. [Java] 内部类的用法
  8. easyui源码翻译1.32--panel(面板)
  9. oracle report err:REP-2103 PL/SQL formula returned invalid value or no value
  10. pyramid的第一个项目
  11. LOJ6277~6285 数列分块入门
  12. cmd实现cab文件的压缩与解压
  13. django中form页面刷新后自动提交的解决方案
  14. The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.
  15. linux 新建用户、用户组 以及为新用户分配权限的基本操作
  16. 【mongoDB】 分享系列
  17. Namespace declaration statement has to be the very first statement or after any declare call in the script
  18. 解决maven jmxtools 缺失的问题
  19. Ubuntu 12.04 安装配置 Apache2
  20. 使用DotNetBarcode制作基本常用条码

热门文章

  1. mysql批量新增的语法
  2. ES6扩展——模板字符串
  3. 高德地图&兴趣点(poi)
  4. 阿里云服务器上部署java项目(安装jdk,tomcat)
  5. vue-父子组件之传值和单项数据流问题
  6. Git使用教程四
  7. shell循环之跳出循环
  8. WHY IS A BYTE 8 BITS? OR IS IT?
  9. Identity角色管理三(创建角色)
  10. CPU到底是什么东西?它为什么能够执行数学运算?