AOP + 自定义注解实现日志打印
1. 先定义个注解,让它作用于方法上
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {}
2. 定义切面
@Aspect
@Component
@Slf4j
public class LogMethodCallAspect {@Pointcut("@annotation(com.wy.spring_demo.aop.annotation.Loggable)")public void logMethodCall() {}@AfterReturning(pointcut = "logMethodCall()", returning = "result")public void logMethodCallAfterReturning(JoinPoint joinPoint, Object result) {long startTime = System.currentTimeMillis();long executionTime = System.currentTimeMillis() - startTime;String className = joinPoint.getTarget().getClass().getSimpleName();String methodName = joinPoint.getSignature().getName();log.info("{}.{} params:{} results: {} execution time: {} ms,",className,methodName,joinPoint.getArgs(),result,executionTime);}}
看上去似乎简简单单,感觉只需要在要打印的方法上加上注解就ok了。
所以简单定义一个controller测试一下
@RestController
@RequestMapping("/log")
public class LogAnnotationTestController {@ResourceLogAnnotationTestController thisController;@Loggable@GetMapping("/test/{name}/{age}")public String test(@PathVariable("name") String name, @PathVariable("age") int age) {return thisController.testService(name, age, "boy");}@Loggablepublic String testService(String name, int age, String sex) {return String.format("%s is %s years old; wy is a %s", name, age, sex);}
}
再整个http发请求
GET http://localhost:8019/log/test/wy/19
小小测试一下,发送请求

请求成功被响应,检查一下日志:

3. 注解失效情况及解决方案
🤔很奇怪,怎么有个注解没生效。。。什么情况,回顾下调用链路:test -> testService,testService上的注解没生效。。。
感觉似曾相识,怎么自定义的注解跟 @Transactional 一样,也会出现失效,于是网上查了一下
在Spring AOP中,如果在同一个类中的方法内部调用另一个方法,AOP切面有时可能无法拦截到被调用的方法,导致B方法上的注解失效。这是因为Spring AOP是基于代理的,而对于内部调用,代理对象内部的方法调用是不会触发切面的。
那么解决方案也有好几种:
-
通过ApplicationContext获取Bean,这样就能保证调用的是讲过sping代理的bean
@Resourceprivate ApplicationContext applicationContext;@Loggable@GetMapping("/test/{name}/{age}")public String test(@PathVariable("name") String name, @PathVariable("age") int age) {LogAnnotationTestController contextBean = applicationContext.getBean(LogAnnotationTestController.class);return contextBean.testService(name, age, "boy");}@Loggablepublic String testService(String name, int age, String sex) {return String.format("%s is %s years old; wy is a %s", name, age, sex);}

-
通过AopContext.currentProxy()获取代理对象进行调用
需要先开启 @EnableAspectJAutoProxy(exposeProxy = true)
在启动类上添加配置

@Loggable@GetMapping("/test/{name}/{age}")public String test(@PathVariable("name") String name, @PathVariable("age") int age) {LogAnnotationTestController logAnnotationTestController = (LogAnnotationTestController) AopContext.currentProxy();return logAnnotationTestController.testService(name, age, "boy");}@Loggablepublic String testService(String name, int age, String sex) {return String.format("%s is %s years old; wy is a %s", name, age, sex);}
相关文章:
AOP + 自定义注解实现日志打印
1. 先定义个注解,让它作用于方法上 Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) public interface Loggable {}2. 定义切面 Aspect Component Slf4j public class LogMethodCallAspect {Pointcut("annotation(com.wy.spring_demo.aop.…...
美团YOLOv6量化部署实战方案
文章目录 1. 背景和难点2. 量化方案实战2.1 重参数化优化器2.1.1 RepOpt2.1.2 RepOpt 版本的 PTQ2.1.3 RepOpt 版本的 QAT2.2 基于量化敏感度分析的部分量化2.3 基于通道蒸馏的量化感知训练2.3.1 通道蒸馏2.3.2 YOLOv6 量化感知蒸馏框架3. 部署时优化3.1 图优化3.1.1 性能分析3…...
hive杂谈
数据仓库是一个面向主题的、集成的、非易失的、随时间变化的,用来支持管理人员决策的数据集合,数据仓库中包含了粒度化的企业数据。 数据仓库的主要特征是:主题性、集成性、非易失性、时变性。 数据仓库的体系结构通常包含4个层次ÿ…...
c语言实现简单的string
文章目录 前言一、注意事项二、代码valgrind扫描总结 前言 在c语言中利用面向对象的编程方式,实现类似c中的string类。 一、注意事项 所有与string结构体相关的函数全都没有返回值。 在c中,当产生临时对象时编译器会自动的加入析构函数,销毁…...
老师应具备什么样的心理素质
老师,一个充满智慧与挑战的职业,就像园丁,用无私的爱和耐心,滋养着每一颗渴望知识的幼苗。那么,作为教育从业者,要具备哪些心理素质呢? 强大的情绪管理能力 老师的工作绝非一帆风顺。在教育学生…...
C语言——单链表(增删改查)
C语言——单链表(增删改查) 一链表一 #include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct Test {int data;struct Test *next; }Link;Link *headNULL;Link* creatHead(Link* head); void AddLinkNode(Link* head,Link newnode); vo…...
Jenkins 保姆级教程
一、什么是流水线 jenkins 有 2 种流水线分为声明式流水线与脚本化流水线,脚本化流水线是 jenkins 旧版本使用的流水线脚本,新版本 Jenkins 推荐使用声明式流水线。文档只介绍声明流水线。 声明式流水线 在声明式流水线语法中,流水线过程定…...
基于 GPS 定位信息的 Pure-Pursuit 轨迹跟踪实车测试(1)
基于 GPS 定位信息的 Pure-Pursuit 轨迹跟踪实车测试(1) 进行了多组实验,包括顺逆时针转向,直线圆弧轨迹行驶,以及Pure-Pursuit 轨迹跟踪测试 代码修改 需要修改的代码并不多,主要对 gps_sensor 功能包和…...
4.25每日一题(通过被积函数和积分区域(不等式)选正确的坐标系求二重积分)
一、正确画出积分区域;通过积分区域和被积函数选择方法 二、如何根据被积函数和积分区域正确选择通过极坐标还是根据直角坐标方程计算: (1)适合极坐标的积分区域:圆或者部分圆 (2)适合极坐标的…...
基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(八)
套餐模块功能开发 1. 新增套餐1.1 需求分析和设计1.1.1产品原型:1.1.2接口设计:1.1.3数据库设计: 1.2 代码开发1.2.1 DishController层1.2.2 DishService接口类1.2.3 DishServiceImpl接口实现类1.2.4 DishMapper层1.2.5 DishMapper.xml1.2.6 …...
Visual NLP:图像信息自动提取的未来
本文旨在以简单的方式解释 Visual NLP 的关键概念,让你了解 Visual NLP 的含义、它的用例是什么、如何使用它以及为什么它是构建自动提取管道的未来 。 NSDT在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在…...
力扣118双周赛
第 118 场双周赛 文章目录 第 118 场双周赛查找包含给定字符的单词最大化网格图中正方形空洞的面积购买水果需要的最少金币数找到最大非递减数组的长度 查找包含给定字符的单词 模拟 class Solution { public:vector<int> findWordsContaining(vector<string>&am…...
网络编程基本概念
网络编程基本概念 为什么需要网络编程? 用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。 与本地打开视频文件类似,只是视频文件这个资源的来源是网络。 相…...
Flutter模板
简介 这个项目是Flutter应用程序的起点。与创建的官方默认模板相比,该项目实现了状态管理等功能,用于Url、本地化等的Navigator 2.0路由。 开始 该项目的入口文件为 ‘lib/init/init.dart’ 特性 状态管理 基于provider. Navigator 2.0适配 代码…...
坐标变换(其一)CSP
坐标变换(其一) 问题描述 对于平面直角坐标系上的坐标 (x,y),小 P 定义了一个包含 n 个操作的序列 T(t1,t2,⋯,tn)。其中每个操作 ti(1≤i≤n)包含两个参数 dxi 和 dyi,表示将坐标 (x,y) 平移至 (xdxi,yd…...
C语言实现万年历
C语言实现万年历 一、项目介绍 需求和功能是用纯C语言实现一个可以属于年份,属于一个年份就可以显示该年各个月份的日历,如同日历一般,每个月当中每天对应的星期均可查看,即万年历,要求格式整齐,星期对照直…...
arp报文及使用go实现
一、ARP协议报文格式及ARP表 ARP(Address Resolution Protocal,地址解析协议)是将IP地址解析为以太网的MAC地址(或者称为物理地址)的协议。在局域网中,当主机或其他网络设备有数据要发送给另一个主机或设备…...
C++ 文件和流、异常处理、动态内存、预处理器
一、C文件和流: 在C中进行文件处理,需要包含头文件<iostream>和<fstream>。fstream标准库定义的三个新的数据类型: 数据类型 描述 ofstream 该数据类型表示输出文件流,用于创建文件并向文件写入信息。 ifstream …...
夜神模拟器 burp抓包 ADB 微信小程序
夜神模拟器 burp抓包 ADB 微信小程序 初始环境准备应用连接证书转换设置夜神模拟器环境ADB配置测试burp抓包 初始环境准备 既然想了解如何抓包,我想大多数是已经安装好 夜神模拟器 和 Burp 了,这里就不在赘述,直接开始操作。 openssl 的下载…...
WPF实战项目十七(客户端):数据等待加载弹框动画
1、在Common文件夹下新建文件夹Events,新建扩展类UpdateLoadingEvent public class UpdateModel {public bool IsOpen { get; set; }}internal class UpdateLoadingEvent : PubSubEvent<UpdateModel>{} 2、新建一个静态扩展类DialogExtensions来编写注册和推…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
