aop切面调用失效问题排查

news2024/11/24 10:43:54

  应用里有较多的地方访问外部供应商接口,由于公网网络不稳定或者外部接口不稳定(重启,发版,ip切换)的原因,经常报502或者504错误。为了解决HTTP调用的500报错,选择使用spring的retryable注解进行重试。给所有的RestTemplate调用的函数都加上了@Retryable注解,本地测试发现好多都不起效果。
  网上搜索有很多帖子反馈@Retryable注解不生效,不生效的点在于:切面切的方法,是在所在的类里被另外的方法调用的,而不是被外部类直接调用。比较难以理解,直接上代码演示:

public class AopClass {

	public void methodA() {
		methodB();
	}
	
	@Retryable
	public void methodB() {
		System.out.println();
	}
}

public class Client{
	public static void main(String[] args) {
		AopClass aop = new AopClass();
		// 切面不会起效
		aop.methodA();
	}
}

  不仅仅是@Retryable有这个问题,所有的切面实现的功能,如果这样调用都有问题。这里通过分析cglib的动态生成的字节码类来分析:

aop代理类

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();

	public Object getProxy(Class clazz) {
		//设置需要创建子类的类
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		//通过字节码技术动态创建子类实例
		return enhancer.create();
	}

	//实现MethodInterceptor接口方法
	public Object intercept(Object obj, Method method, Object[] args,
	                        MethodProxy proxy) throws Throwable {
		System.out.println("前置代理");
		//通过代理类调用父类中的方法
		Object result = proxy.invokeSuper(obj, args);
		System.out.println("后置代理");
		return result;
	}
}

被代理类

public class SayHello {

	public void callee() {
		System.out.println("hello everyone");
	}
	
	public void caller() {
		this.callee();
	}
}

配置好-Dcglib.debugLocation参数

查看动态生成的类(第三个)
在这里插入图片描述

通过反编译工具查看class文件

public class SayHello$$EnhancerByCGLIB$$11ca72e0 extends SayHello implements Factory {
	private MethodInterceptor CGLIB$CALLBACK_0;
	
    public final void caller() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }
		
		// 如果被代理
        if (var10000 != null) {
            var10000.intercept(this, CGLIB$caller$0$Method, CGLIB$emptyArgs, CGLIB$caller$0$Proxy);
        } else {
        // 如果没被代理
            super.caller();
        }
    }
}

  通过生成的类可以发现,如果直接调用没被代理的方法,那么调用的是父类SayHello的方法,也就是没被加强的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/489696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode292. Nim 游戏

Every day a leetcode 题目来源:292. Nim 游戏 解法1:数学推理 让我们考虑一些小例子。 显而易见的是,如果石头堆中只有一块、两块、或是三块石头,那么在你的回合,你就可以把全部石子拿走,从而在游戏中…

李沐动手学深度学习 v2 实战Kaggle比赛:预测房价

前言 最近学习一些深度学习知识,观看了李沐老师的《动手学深度学习》的视频 练习一下 实战Kaggle比赛:预测房价 巩固一下 前面学习的知识, 不coding一下总感觉什么也没学 陆陆续续调了一天 记录一下 导包 %matplotlib inline import numpy…

计算机网络第二章(谢希仁第八版)

作者:爱塔居 专栏:计算机网络 作者简介:大三学生,希望和大家一起进步 文章目录 目录 文章目录 前言 一、物理层的基本概念 1.1 物理层协议的主要任务 1.2 传输媒体(了解) 二、传输方式 2.1 串行传输…

第二十八章 Unity射线检测

本章节我们介绍一下射线。射线就是从一个固定点向一个方向发射出一条直线,在发射过程中需要判断该射线有没有与游戏物体发送碰撞。射线既可以用来检测射击游戏中武器指向目标;又可以判断鼠标是否指向游戏物体。射线的创建方式,一般使用代码来…

11. Kubernetes 开章

本章讲解知识点 Kubernetes 概念为什么要使用 KubernetesKubernetes 的部署架构Kubernetes 基本命令本章主要是针对 Kubernetes 基本概念为读者讲解,读者能有一个大概印象即可,不需要过于斟酌细节,针对 Kubernetes 的概念将在后面章节中详细讲解。 1. Kubernetes 概念 我们…

学习Transformer前言(Self Attention Multi head self attention)

一、前言 一直在做项目,也比较懒没有挤出时间去学习新的东西,感觉停滞很久了,好长一段时间都没有新的知识输入,早就需要就去学习transformer了,因此先来学习注意力机制,本文为个人的一个笔记总结。主要是基…

Linux系统编程(三)—— 文件编程(3)进程环境

一、main函数 现在的格式:int main(int argc, char *argv[])以前的main函数有三个参数,另一个参数就是环境变量 二、进程的终止(两种都要背下来) 2.1 正常终止 (1)从main函数返回 main函数被称为程序的…

第10章:堆

堆是什么? 堆是一种特殊的完全二叉树。 完全二叉树:每层节点都完全填满,最后一层若是没填满,则只缺少右边的节点。所有的节点都大于等于(最大堆)或小于等于(最小堆)它的子节点。jav…

软考——数据结构,算法基础,程序设计语言,法律法规,多媒体基础

数据结构与算法基础 数组与矩阵线性表广义表树与二叉树图排序与查找算法基础及常见算法 数组 稀疏矩阵 直接把(0,0)带入,排除B,C 将(1,1)带入,排除D, 最终…

Python | 人脸识别系统 — 博客索引

本博客为人脸识别系统的博客索引 工具安装、环境配置:Python | 人脸识别系统 — 简介 1、UI代码 UI界面设计:Python | 人脸识别系统 — UI界面设计UI事件处理:Python | 人脸识别系统 — UI事件处理 2、用户端代码 用户端博客索引:…

Jupyter Notebook入门教程

Jupyter Notebook(又称Python Notebook)是一个交互式的笔记本,支持运行超过40种编程语言。本文中我们将介绍Jupyter Notebook的主要特点,了解为什么它能成为人们创造优美的可交互式文档和教育资源的一个强大工具。 首先&#xff…

vue diff算法与虚拟dom知识整理(4) h函数虚拟节点嵌套

那么 先补充上文有一个没强调的点 h函数 当你不需要属性时 其实是可以不传的 例如 我们打开案例 打开 src下的index.js 修改代码如下 import {init,classModule,propsModule,styleModule,eventListenersModule,h,} from "snabbdom";//创建patch函数const patch ini…

CUBLAS 和 CUDNN

文章目录 一、什么是CUBLASCUBLAS实现矩阵乘法CUBLAS中的Leading DimensionCUBLAS LEVEL3函数 : 矩阵矩阵CUBLAS实现矩阵乘法 二、cuDNN使用CuDNN实现卷积神经网络 四、CUBLAS和CUDNN实践 一、什么是CUBLAS cuBLAS是BLAS的一个实现。BLAS是一个经典的线性代数库&am…

解决C语言的缺陷【C++】

文章目录 命名空间展开了命名空间域指定访问命名空间域域作用限定符命名空间定义 C输入&输出缺省参数全缺省参数半缺省参数缺省参数应用 函数重载参数类型不同参数个数不同参数类型顺序不同 引用引用的特性引用在定义时必须初始化一个变量可以有多个引用引用一旦引用一个实…

基于Radon-分数傅里叶变换对消器的海杂波弱目标检测

海面微弱目标检测面临的主要困难来自: 慢速小目标回波微弱;空时变海杂波异常复杂,海杂波特性认知难度大;目标模型难以建立;目标、海杂波类别非平衡。 ARU效应 是由于海面波浪的起伏和涟漪引起的。在雷达回波信号中&am…

nodejs开发 | 安全工具端口扫描器

今天分享一个nodejs的demo,可以扫描出指定IP的端口开放情况。 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8…

[笔记]Python计算机视觉编程《一》 基本的图像操作和处理

文章目录 前言环境搭建 计算机视觉简介Python和NumPy第一章 基本的图像操作和处理1.1 PIL:Python图像处理类库1.1.1 转换图像格式1.1.2 创建缩略图1.1.3 复制和粘贴图像区域1.1.4 调整尺寸和旋转 1.2 Matplotlib1.2.1 绘制图像、点和线 前言 今天,图…

python基础实战6-python字符串

1字符串的表达方式 字符串是 Python 中最常用的数据类型。我们可以使用引号 ( 或 " ) 来创建字符串。 字符串表达方式 a " I m Tom" #一对双引号 b ’Tom said:" I am Tom" #一对单引号 c ‘Tom said: " I\m Tom" #转义字符 d T…

python库,科学计算与数据可视化基础,知识笔记(numpy+matplotlib)

文章目录 1、numpyndarray对象,数组指定形状创建(要会)数组的索引,切片与遍历(要会)数组的相加,转置,展开(要会)数组元素增删改查(最好会&#xf…

当CRM遇见ChatGPT,AI如何帮销售打造“最强大脑”

导读:这一轮AI浪潮将对CRM企业带来哪些新机遇? ChatGPT诞生至今不过100多天,但它已经对很多行业产生了巨大影响。 企业直面市场的一线战场——销售、营销、客服等领域也是如此。以ChatGPT为代表的人工智能技术热潮正在改变着传统营销、销售的…