基于Spring AOP实现自定义注解
温馨提示:
本文最后更新于 2024年02月25日,已超过 332 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
我们日常开发中,经常使用注解来完成很多工作,比如使用@Transactional
来声明事务,而不需要手动编写事务逻辑,给我们日常开发带来很大便利。
现在我这里有记录博客所有接口的访问日志的需求,比如谁(IP)在什么时候访问了什么接口。
我们当然可以在想记录所有接口都增加记录日志的方法,但这样显然增加了大量的共性代码,而且也增加了主流程的风险,如果日志记录出错可能会让主业接口务异常,这显然不是我们希望的。
此时我们就可以想到,能不能像声明式事务一样使用注解来声明一下,告知Spring这里需要记录日志,至于日志怎么记录,我业务接口是不需要关心的。接下来我们就来尝试一下:
1.我们来定义一个注解,用来声明记录业务日志
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
/** 接口的名称 */
String value() default "";
/** 当前日志记录位置 */
String storage() default "console";
String mysql = "MySQL";
}
@Target({ElementType.METHOD})
:定义我们注解使用的位置,这里是方法上@Retention(RetentionPolicy.RUNTIME)
:定义我们的自定义注解保留多久,这里是运行时都保留value()
:自定义方法名,标明接口的名称storage()
:自定义方法名,标明接口输出(存储)位置
这里面的方法不是必须的,可根据自己的需求来自定义,最简单的就是什么都不写
2.切面逻辑如下:
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Around("@annotation(log)")
public Object writeLog(ProceedingJoinPoint point, Log log) throws Throwable {
//先执行业务
Object result = point.proceed();
try {
ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (Objects.nonNull(attributes)) {
HttpServletRequest request = attributes.getRequest();
String ip = request.getHeader("x-real-ip");
String value = log.value();
if (Log.mysql.equals(log.storage())){
// 记录数据库
} else {
logger.info("日志控台输出 {} 访问了 {}", ip, value);
}
}
} catch (Exception e) {
logger.error("日志记录出错! {}", e.getMessage());
}
return result;
}
}
@Aspect
:标明当前对象是一个界面逻辑
3.自定义注解使用方法如下,在接口上加上@Log(value = "下单接口")
就可以了,当然value
和storage
方法都可以不填直接写@Log
也没问题:
@PostMapping("/order")
@Log(value = "下单接口")
public ResponseVO<String> order(Long goodsId, Long userId) {
return orderService.order(goodsId, userId);
}
4.输出日志:
控台输出日志 **** 访问了 下单接口
如此,一个简单又实用的自定义注解功能就这样完成了,就是如此简单。在我们日常开发中有很多类似的场景都可以使用该方案解决,比如:
- 记录指定方法出入参、执行时间等信息,可用于后期调优
- 接口鉴权,对接口的请求进行安全性校验
- 接口请求统计,自定义限流、快速熔断、服务降级等等
- 指定方法共性入参校验
......
正文到此结束
- 本文标签: java spring AOP
- 本文链接: https://www.58cto.cn/article/44
- 版权声明: 本文由程序言原创发布, 非商业性可自由转载、引用,但需署名作者且注明文章出处:程序言 》 基于Spring AOP实现自定义注解 - https://www.58cto.cn/article/44