java 注解结合 spring aop 自动输出日志新增拦截器与过滤器
auto-log
auto-log 是一款为 java 设计的自动日志监控框架。
前面已经写过了两篇:
java 注解结合 spring aop 实现日志 traceId 唯一标识
经过前面2篇的代码实现,发现依然存在下列问题:
(1)注解的使用依然不够便捷。
如果每一个方法上都指定 @AutoLog,依然会比较麻烦。个人在使用的时候也不想这么麻烦。
于是想添加基于类的注解。
后期考虑是否可以基于包,动态指定 AOP 的扫描包范围。
(2)对于日志的处理过于单一。
比如我想添加所有操作的审计日志,然后存储到数据库。同时日志输出不变。
发现以前的日志框架,不能很好的支撑。于是想添加日志输出的拦截器。
(3)对于参数的过滤
以前是直接基于 toString() 实现,发现有些人比较懒不写 toString(比如我),那么参数打印的信息就没有意义。
于是替换成立 FastJSON,但是引来了新的问题,比如 HttpRequest 等参数直接序列化是会报错的,于是想添加基于参数的过滤器实现。
需求,才是最好的创作动力。
目前共计经过了 12 个版本的迭代,上面 3 个特性已经满足。
特性
基于注解+字节码,配置灵活
自动适配常见的日志框架
支持编程式的调用
支持注解式,完美整合 spring
支持整合 spring-boot
支持慢日志阈值指定,耗时,入参,出参,异常信息等常见属性指定
支持 traceId 特性
支持类级别定义注解
支持自定义拦截器和过滤器
快速开始
maven 引入
<dependency>
<group>com.github.houbb</group>
<artifact>auto-log-core</artifact>
<version>${最新版本}</version>
</dependency>
入门案例
UserService userService = AutoLogHelper.proxy(new UserServiceImpl());
userService.queryLog("1");
- 日志如下
[INFO] [2020-05-29 16:24:06.227] [main] [c.g.h.a.l.c.s.i.AutoLogMethodInterceptor.invoke] - public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) param is [1]
[INFO] [2020-05-29 16:24:06.228] [main] [c.g.h.a.l.c.s.i.AutoLogMethodInterceptor.invoke] - public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) result is result-1
代码
其中方法实现如下:
- UserService.java
public interface UserService {
String queryLog(final String id);
}
- UserServiceImpl.java
直接使用注解 @AutoLog 指定需要打日志的方法即可。
public class UserServiceImpl implements UserService {
@Override
@AutoLog
public String queryLog(String id) {
return "result-"+id;
}
}
TraceId 的例子
代码
UserService service = AutoLogProxy.getProxy(new UserServiceImpl());
service.traceId("1");
其中 traceId 方法如下:
@AutoLog
@TraceId
public String traceId(String id) {
return id+"-1";
}
测试效果
信息: [ba7ddaded5a644e5a58fbd276b6657af] <traceId>入参: [1].
信息: [ba7ddaded5a644e5a58fbd276b6657af] <traceId>出参:1-1.
其中 ba7ddaded5a644e5a58fbd276b6657af 就是对应的 traceId,可以贯穿整个 thread 周期,便于我们日志查看。
注解说明
@AutoLog
核心注解 @AutoLog 的属性说明如下:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| enable | boolean | true | 是否启用 |
| param | boolean | true | 是否打印入参 |
| result | boolean | true | 是否打印出参 |
| costTime | boolean | false | 是否打印耗时 |
| exception | boolean | true | 是否打印异常 |
| slowThresholdMills | long | -1 | 当这个值大于等于 0 时,且耗时超过配置值,会输出慢日志 |
| description | string | "" | 方法描述,默认选择方法名称 |
| interceptor | Class[] | 默认实现 | 拦截器实现,支持指定多个和自定义 |
| paramFilter | Class | 空 | 入参过滤器,支持自定义 |
@TraceId
@TraceId 放在需要设置 traceId 的方法上,比如 Controller 层,mq 的消费者,rpc 请求的接受者等。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| id | Class | 默认为 uuid | traceId 的实现策略 |
| putIfAbsent | boolean | false | 是否在当前线程没有值的时候才设置值 |
| enable | boolean | true | 是否启用 |
| interceptor | Class[] | 默认实现 | 拦截器实现,支持指定多个和自定义 |
自定义策略
自定义日志拦截器(interceptor)
内置拦截器
AutoLogInterceptor 默认实现
定义
直接继承自 AbstractAutoLogInterceptor 类,并且实现对应的方法即可。
public class MyAutoLogInterceptor extends AbstractAutoLogInterceptor {
@Override
protected void doBefore(AutoLog autoLog, IAutoLogInterceptorContext context) {
System.out.println("自定义入参:" + Arrays.toString(context.filterParams()));
}
@Override
protected void doAfter(AutoLog autoLog, Object result, IAutoLogInterceptorContext context) {
System.out.println("自定义出参:" + result);
}
@Override
protected void doException(AutoLog autoLog, Exception exception, IAutoLogInterceptorContext context) {
System.out.println("自定义异常:");
exception.printStackTrace();
}
}
使用
如下,这样日志输出,就会使用上面的指定策略。
@AutoLog(interceptor = MyAutoLogInterceptor.class)
public String my() {
return "自定义策略";
}
自定义入参过滤器(paramFilter)
内置
WebParamFilter 主要用于过滤 HttpRequest HttpServlet 等无法直接 JSON 序列化的对象。
自定义
直接继承 AbstractParamFilter 类实现对应的方法即可。
public class MyParamFilter extends AbstractParamFilter {
@Override
protected Object[] doFilter(Object[] params) {
Object[] newParams = new Object[1];
newParams[0] = "设置我我想要的值";
return newParams;
}
}
使用
指定对应的参数过滤器。这样,无论入参是什么,都会变成我们指定的 [设置我我想要的值]。
@AutoLog(paramFilter = MyParamFilter.class)
public String paramFilter() {
return "自定义入参过滤器";
}
spring 整合使用
完整示例参考 SpringServiceTest
注解声明
使用 @EnableAutoLog 启用自动日志输出
@Configurable
@ComponentScan(basePackages = "com.github.houbb.auto.log.test.service")
@EnableAutoLog
public class SpringConfig {
}
测试代码
@ContextConfiguration(classes = SpringConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringServiceTest {
@Autowired
private UserService userService;
@Test
public void queryLogTest() {
userService.queryLog("1");
}
}
- 输出结果
信息: public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) param is [1]
五月 30, 2020 12:17:51 下午 com.github.houbb.auto.log.core.support.interceptor.AutoLogMethodInterceptor info
信息: public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) result is result-1
五月 30, 2020 12:17:51 下午 org.springframework.context.support.GenericApplicationContext doClose
springboot 整合使用
maven 引入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>auto-log-springboot-starter</artifactId>
<version>最新版本</version>
</dependency>
只需要引入 jar 即可,其他的什么都不用配置。
使用方式和 spring 一致。
测试
@Autowired
private UserService userService;
@Test
public void queryLogTest() {
userService.query("spring-boot");
}
开源地址
Road-Map
- 优化日志中的方法路径名称
考虑补全对应的类信息
- 全局配置
比如全局的慢日志阈值设置等
jvm-sandbox 特性
编译时注解特性
原文地址

java 注解结合 spring aop 自动输出日志新增拦截器与过滤器的更多相关文章
- Spring Boot项目中如何定制拦截器
本文首发于个人网站:Spring Boot项目中如何定制拦截器 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供Han ...
- 基于注解的Spring AOP的配置和使用
摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...
- 基于注解的Spring AOP的配置和使用--转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(三)创建代理对象
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- Java动态代理-->Spring AOP
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(二)筛选合适的通知器
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(一)入口
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 基于注解的Spring AOP示例
基于注解的Spring AOP示例 目录 在XML配置文件中开启 @AspectJ 支持 声明切面及切入点 声明通知 测试 结语 在XML配置文件中开启 @AspectJ 支持 要使用Spring的A ...
- Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现
转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...
- spring AOP AspectJ 定义切面实现拦截
总结记录一下AOP常用的应用场景及使用方式,如有错误,请留言. 1. 讲AOP之前,先来总结web项目的几种拦截方式 A: 过滤器 使用过滤器可以过滤URL请求,以及请求和响应的信息,但是过 ...
随机推荐
- 解决在Edge浏览器中使用不了(找不到)new bing的情况
1.问题 我们有时候看不到下图圈出部分的信息,无法找到New Bing的入口(这边是空的) 2.解决方式 1.选择右上角的三条杠,并选择其中的settings 2.将其中的country一项改为外国即 ...
- css - absolute居中
position:absolut; left:50%; top:50%; margin-left: -(自身一半宽度); margin-top: -(自身一半高度)
- [转帖]Oracle 性能优化 之 游标及 SQL
https://www.cnblogs.com/augus007/articles/9273236.html 一.游标 我们要先说一下游标这个概念. 从 Oracle 数据库管理员的角度上说,游标是对 ...
- [转帖]Oracle参数解析(parallel_force_local)
https://www.modb.pro/db/122032 是否需要增加这个参数? 往期专题请查看www.zhaibibei.cn这是一个坚持Oracle,Python,MySQL原创内容的公众号 ...
- [转帖]12.JVM运行时数据区之虚拟机栈概述
https://blog.csdn.net/u011069294/article/details/107050001 目录 1. 内存中的栈与堆 2.栈的优点 1. 内存中的栈与堆 栈是运行时单位,堆 ...
- [转帖]sudo 命令_su、sudo、sudo su、sudo -i的用法和区别
sudo 命令 1.sudo 简介 sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如halt,reboot,su等等.这样不仅减少了root用户 ...
- [转帖]MySQL 8.0新特性和性能数据
https://plantegg.github.io/2022/07/03/MySQL8.0%E7%9A%84%E4%B8%80%E4%BA%9B%E6%95%B0%E6%8D%AE/ MySQL 8 ...
- 原生js拖拽元素(onmouseup不能够触发的原因)
我们经常会遇见拖拽某一个元素的场景,拖拽也是很常用的: 这次拖拽遇见一个问题,有时在拖拽的时候吗,鼠标松开,元素仍然可以拖拽: 经过查阅资料,发现: 会触发H5原生的拖拽事件.并且不会监听到onmou ...
- Machine Learning | Coursera 课后代码
Machine Learning | Coursera GitHub地址:https://github.com/hanlulu1998/Coursera-Machine-Learning Machin ...
- Go基础之指针
Go语言中的指针 目录 Go语言中的指针 一.Go语言中的指针介绍 1.1 指针介绍 1.2 基本语法 1.3 声明和初始化 1.4 Go 指针的3个重要概念 1.4.1 指针地址(Pointer A ...