首页 > 其他分享 >动态代理中debug设置断点会执行invoke方法且args为null的原因

动态代理中debug设置断点会执行invoke方法且args为null的原因

时间:2024-03-05 13:58:56浏览次数:28  
标签:真实 target invoke 对象 方法 args 调度 debug 断点

情景
写了个proxyExample,运行一看,竟然debug的结果跟run的结果竟然不一样,debug中会多次执行invoke方法,且并不调用sayHello方法

代码

public class ProxyExample implements InvocationHandler {
private Object target;
/**
* 创建代理,将真实对象的类、构造方法等信息告诉代理类并将代理类返回,此时代理类拥有真实类的一切,
* 甚至就可以直接看作是真实类的实例。
* @param target
* @return
*/
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader() , target.getClass().getInterfaces() , this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//debug:加上方法名看看调用的是什么
System.out.println("调度真实对象之前,方法名: " + method.getName() + args);
Object obj = method.invoke(target , args);
System.out.println("调度真实对象之后");
return obj;
}
public static void main(String[] args) {
ProxyExample example = new ProxyExample();
HelloWorld proxy = (HelloWorld) example.bind(new HelloWorldImpl());
proxy.sayHelloWorld();

}
}

debug运行结果
调度真实对象之前,方法名: toStringnull
调度真实对象之后
调度真实对象之前,方法名: toStringnull
调度真实对象之后
调度真实对象之前,方法名: sayHelloWorldnull
调度真实对象之前,方法名: toStringnull
调度真实对象之后
[INFO ] 2019-10-09 20:52:26 [main] [javalearning.proxytest.HelloWorldImpl] javalearning.proxytest.HelloWorldImpl.sayHelloWorld(HelloWorldImpl.java:17): Hello World!
调度真实对象之前,方法名: toStringnull
调度真实对象之后
调度真实对象之后
调度真实对象之前,方法名: toStringnull
调度真实对象之后
调度真实对象之前,方法名: toStringnull
调度真实对象之后
Disconnected from the target VM, address: '127.0.0.1:55000', transport: 'socket'

Process finished with exit code 0
run运行结果
调度真实对象之前,方法名: sayHelloWorldnull
[INFO ] 2019-10-09 21:19:41 [main] [javalearning.proxytest.HelloWorldImpl] javalearning.proxytest.HelloWorldImpl.sayHelloWorld(HelloWorldImpl.java:17): Hello World!
调度真实对象之后
Process finished with exit code 0
发现端倪
发现我单步调试时,

1.出现tostring的次数跟暂停的次数成正比,单步调试越多,invoke打印越多;

2.run模式下就没那么多打印,仅有想要的sayHello方法结果

3.如果我把断点禁用掉(把断点红色变灰的那个按钮),那么禁用之后不再打印invoke的东西,仅有sayHello方法结果

 

这样基本就能确定,多次调用invoke必定跟打断点有关系

探索
所以看看调用的到底是啥咯,也就是上面代码中的这一行:

//debug加上方法名看看调用的是什么
System.out.println("调度真实对象之前,方法名: " + method.getName() + args);
可以看到打印结果,被调用的方法名是tostring,猜是idea中debug程序自带的问题,以下是引用内容,

鸣谢lkforce:

断点处暂停时,IDEA会调用被代理类的toString()方法获取相关信息,鼠标悬停显示的好像就是那个东西。由于代理类代理该类的所有方法(包括toString),因此暂停一次就会输出一次“调用了toString()方法”的相关信息

多数情况下调用一下toString()方法没有什么问题,但是也有例外,比如重写了toString()方法的类,随意的调用toString()方法会导致未知的问题,比如Dubbo的AbstractConfig类,对这个类的debug会导致其子类ReferenceConfig的initialized属性错误的被修改为true,进而无法正确的生成Dubbo代理。

另外,IDEA在debug时调用toString()方法的情况是可以在配置中关掉的,配置位置是

Settings->Build,Execution,Development->Debugger->Java->Enable ‘toString()’ object view

 

https://blog.csdn.net/q2878948/article/details/102491389

标签:真实,target,invoke,对象,方法,args,调度,debug,断点
From: https://www.cnblogs.com/dousnl/p/18053886

相关文章

  • PowerShell 中,您可以通过远程控制执行多条命令。最常见的方法是使用 Invoke-Command
    PowerShell中,您可以通过远程控制执行多条命令。最常见的方法是使用Invoke-Command命令,它允许您在远程计算机上执行指定的命令或脚本块。以下是一种执行多条命令的示例:powershellCopyCodeInvoke-Command-ComputerName"远程计算机名"-ScriptBlock{#在这里可以放置要......
  • 网页浏览器Chrome开发者调试工具-Source(源码)-断点调试、条件断点、日志断点
    前言全局说明网页浏览器Chrome开发者调试工具-Source(源码)-断点调试、条件断点、日志断点断点,是某行代码要执行,还没有执行的一个暂停点一、截图对照1.1Chrome浏览器1.1.1蓝色,普通断点1.1.2设置断点类型图中分别是:backpoint:普通断点(蓝色)Conditionalbreakp......
  • 【XInput】手柄模拟鼠标运作之 .NET P/Invoke 和 UWP-API 方案
    上一篇中,老周简单肤浅地介绍了XInputAPI的使用,并模拟了鼠标移动,左、右键单击和滚轮。本篇,咱们用.NET代码来完成相同的效果。说起来也是倒霉,博文写了一半,电脑忽然断电了。不知道什么原因,可能是UPS电源出故障。重新开机进来一看,博文没有自动保存到草稿箱。我记得以前是有自......
  • VScode 配置php调试环境变量. phpstudy + nginx+ php7.4, 解决无法断点问题
    参考大佬的帖子https://www.cnblogs.com/hfdp/p/17028596.htmlhttps://blog.csdn.net/qq_61739597/article/details/132433472 (远程调试)踩坑经验我从phpstudy添加好网站才进行配置.当配置好之后,一直没有断点下来. 非常郁闷找不到问题. 写了一个demo,php文件,通过......
  • 矩阵爆破逆向之条件断点的妙用
    不知道你是否使用过IDA的条件断点呢?在IDA进阶使用中,它的很多功能都有大作用,比如:ida-trace来跟踪调用流程。同时IDA的断点功能也十分强大,配合IDA-python的输出语句能够大杀特杀!那么本文就介绍一下这个功能点,使用z3来秒解题目。条件断点什么是条件断点呢?条件断点(ConditionalBrea......
  • 判断点在封闭多边形内部
    判断点在一个面域的内部前言作者在学习工作中,经常需要和几何相关内容打交道,因此分享自己在编程过程中遇到的一些问题和解决方法,也十分欢迎各位私信与我交流,另外如有不懂得地方也可以找我,在下会积极回复。问题分析通常来说,人眼能一眼就看出一个点是否处于面内,但是如何让计算机......
  • 核心子方法5: invokeBeanFactoryPostProcessors(beanFactory)方法详解
    先总结: 该方法通过指定顺序,遍历调用各种实现了BeanDefinitionRegistryPostProcessor接口或BeanFactoryPostProcessor接口,的beanFactory后处理器注: BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口调用顺序: 1.先调用已经提前放入Applicat......
  • 关于 ‘--exec’ 参数( find 命令)及介绍 ‘xargs ’命令区别
    findgoal.log.*.gz-mtime+2-execrm-rf{}\;findgoal.log.*.gz-mtime+3|xargsrm-f前言:find命令一直都是系统管理员的常用命令之一,其参数中“-exec”尤其实用。而“xargs”命令,针对查询也有属于自己的见解。本文着重讲解的是围绕find命令查询为主线,使用-exe......
  • 前端调试断点方面
    前端调试断点方面目录前端调试断点方面前端报错出了问题debugger前端报错出了问题后端没问题但页面显示不是预想的样式,出现问题,F12进入Network找哪一个请求出了问题,找到那一个请求:然后去前端全局查找ctrl+shift+R找到import的就是引入使用此方法的地方然后看......
  • phpstorm开启debug断点调试模式
    查看php版本查看自己php的版本,使用:phpinfo()函数<?phpechophpinfo();XdebugXdebug:Support—TailoredInstallationInstructions右击查看index.php源代码并复制到Xdebug中点击分析查看分析结果修改php配置文件vi/opt/homebrew/etc/php/7.4/conf.d/99-xdebug.......