idea插件开发之一起来开发个打印方法入参和返回值的插件吧!

2024-06-22 06:30

本文主要是介绍idea插件开发之一起来开发个打印方法入参和返回值的插件吧!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面

源码 。
在开发过程中为了调试代码我们就可能就需要知道某个方法入参的值是什么,或者是返回值是什么。此时,我们的解决办法一般都是debug,但是debug的效率说实话其实是不高的,特别是不断的调试,不断的debug。所以为了解决(😅,彻底解决不用debug,不太可能,但肯定能在一定程度上缓解吧)这个痛点问题,我们就来尝试开发一个idea插件吧。

1:编写agent程序

通过bytebuddy来实现字节码插桩,源码如下:

public class MyPreAgent {// 如果有该方法则优先调用这个有两个参数的方法public static void premain(String agentArgs, Instrumentation inst) {AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {return builder
//                    .method(ElementMatchers.named("executeInternal")) // 拦截任意方法.method(ElementMatchers.named("m1").or(ElementMatchers.named("m2"))) // 拦截任意方法.intercept(MethodDelegation.to(MonitorMethod.class)); // 委托};new AgentBuilder.Default()
//                .type(ElementMatchers.nameStartsWith("com.mysql.cj.jdbc.ClientPreparedStatement")).type(ElementMatchers.nameStartsWith("com.dahuyou.agent.test.MyCls")).transform(transformer).installOn(inst);}// 如果是没有上面的方法则调用这个一个参数的方法public static void premain(String agentArgs) {}}

在代码中我们设置了满足什么规则才拦截,这里是固定写死的拦截类com.dahuyou.agent.test.MyCls的方法m1和m2,当然可以随意改,或者是通过某种配置的方式做成活的,上述的类MonitorMethod即为插装的代码,源码如下:

public class MonitorMethod {@RuntimeTypepublic static Object intercept(@This Object obj, @Origin Method method, @SuperCall Callable<?> callable, @AllArguments Object... args) throws Exception {System.out.println("MonitorMethod.intercept...");long start = System.currentTimeMillis();Object resultObj = null;try {resultObj = callable.call();return resultObj;} finally {System.out.println("方法名称:" + method.getName() + "入参个数:" + method.getParameterCount());for (int i = 0; i < method.getParameterCount(); i++) {System.out.println("入参 Idx:" + (i + 1) + " 类型:" + method.getParameterTypes()[i].getName() + " 内容:" + args[i]);}System.out.println("出参类型:" + method.getReturnType().getName());System.out.println("出参结果:" + resultObj);System.out.println("方法耗时:" + (System.currentTimeMillis() - start) + "ms");}}}

接着我们就可以生成agent的jar包来测试了,如下:
在这里插入图片描述
然后创建一个满足agent匹配规则的类:

public class MyCls {public String m1(String name) {System.out.println("m1方法执行了啊: " + name);this.m2(30, "一个啊神秘的地方");return name;}private int m2(int age, String addr) {System.out.println("m2方法执行了啊: " + age);return ++age;}
}

测试类:

public class MyPreAgentTest {public static void main(String[] args) {String name = "张三";new MyCls().m1(name);}
}

然后配置VM option添加-javaagent,如下:
在这里插入图片描述
最后运行测试:
在这里插入图片描述

接着就可以来继续开发插件了。

2:编写idea插件

要想让agent工作,必须通过-javaagent添加到java运行命令中,idea提供了java.programPatcher的扩展可以让我们实现这个需求,具体是继承抽象类JavaProgramPatcher,然后修改其中的入参RunProfile:

/*** 向Java cmd中动态添加-javaagent:xxx*/
public class JavaCmdEditor extends JavaProgramPatcher {@Overridepublic void patchJavaParameters(Executor executor, RunProfile configuration, JavaParameters javaParameters) {String agentCoreJarPath = PluginUtil.getAgentCoreJarPath();RunConfiguration runConfiguration = (RunConfiguration) configuration;ParametersList vmParametersList = javaParameters.getVMParametersList();// 向运行参数中增加-javaagent:/path/to/the-show-sql-agent.jarvmParametersList.addParametersString("-javaagent:" + agentCoreJarPath);vmParametersList.addNotEmptyProperty("com.dahuyou.the-probe-plugin", runConfiguration.getProject().getLocationHash());}
}

这样还不行,为了让idea加载运行,还需要配置到plugin.xml中的java.ProgramPatcher中:

<extensions defaultExtensionNs="com.intellij"><!-- Add your extensions here --><java.programPatcher implementation="com.dahuyou.probe.plugin.JavaCmdEditor"/>
</extensions>

然后就可以来测试了:
在这里插入图片描述
运行:
在这里插入图片描述
到这里还有一个问题需要解决,即插装的类和方法是固定写死的,接下来我们开发一个UI来允许配置想要拦截的类和方法,就基本全了。

3:插桩代码支持配置

首先开发一个action,在file中增加一个按钮入口:

public class AgentSettingAction extends AnAction {@Overridepublic void actionPerformed(AnActionEvent e) {Messages.showInfoMessage("即将跳转到agent设置页面", "提示");// 弹出一个设置(implements Configurable)页面(extends JPanel)ShowSettingsUtil.getInstance().editConfigurable(e.getProject(), new AgentSettingUI());}
}

这里AgentSettingUI是需要我们自定义的页面,继承了Japnel,并实现了Configurable接口:

public class AgentSettingUI extends JPanel implements Configurable {}

效果如下:
在这里插入图片描述
点击ok会调用apply方法,在该方法中会将用户设置的信息写到本地文件中:
在这里插入图片描述
接着还需要改造agent程序,动态的从文件中读取数据来进行拦截配置:

public static void premain(String agentArgs, Instrumentation inst) {String agentSettingFilePath = "D:/agentsetting.txt";String packagePrefix = "";List<String> methodList = null;try {BufferedReader br = new BufferedReader(new FileReader(agentSettingFilePath));String agentSettingInfo = br.readLine();// com.dahuyou3343#tttmyFn1,myFn2System.out.println("agentSettingInfo: " + agentSettingInfo);String[] split = agentSettingInfo.split("#");packagePrefix = split[0];methodList = Arrays.asList(split[1].split(","));System.out.println("packagePrefix: " + packagePrefix);System.out.println("methodList111: " + methodList);} catch (Exception e) {e.printStackTrace();}List<String> finalMethodList = methodList;AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {ElementMatcher.Junction<NamedElement> named = ElementMatchers.named(finalMethodList.get(0));for (int i = 1; i < finalMethodList.size(); i++) {named = named.or(ElementMatchers.named(finalMethodList.get(i)));}return builder.method(named) // 拦截任意方法.intercept(MethodDelegation.to(MonitorMethod.class)); // 委托};new AgentBuilder.Default().type(ElementMatchers.nameStartsWith(packagePrefix)).transform(transformer).installOn(inst);
}

注意打一个新的agent jar包放在插件模块的libs目录中,接着我们来测试,只拦截m1,不拦截m2:
在这里插入图片描述
在这里插入图片描述
设置一个错误的包前缀,都不拦截:
在这里插入图片描述
在这里插入图片描述

4:在idea中安装

首先打包:
在这里插入图片描述
安装到idea也比较简单,你可以直接下载 然后安装到你的idea中,安装也很简单,可以直接拖拽到idea中松手,会提示你重启,也可以通过file->settings->plugins:
在这里插入图片描述
然后选择zip包安装,也会提示你重启idea,重启后就可以使用该插件了,对了插件的名字叫:debug小助手
在这里插入图片描述

5:实际使用

假设有如下的springboot项目:

@SpringBootApplication
@RestController
public class AAApplication {public static void main(String[] args) {SpringApplication.run(AAApplication.class);}@RequestMapping("/sayHi")@ResponseBodypublic String sayHi(String name) {new MyCls().m1(name);return name + ",hi!";}
}

测试同学说你的sayHi接口,错误,此时如果你怀疑是入参问题,就可以用这个插件了(是不是就不用debug了🤭🤭🤭,提高效率杠杆的),如下:
在这里插入图片描述

你安装使用了吗?是的话就点个赞让我知道下吧🙁🙁🙁!!!如果你有对这个插件有什么建议,或者其他的想法,就留言告诉我吧,我们一起进步,让自己在这互联网寒潮中不做那批被淘汰的人💪💪💪!!!

写在后面

参考文章列表

Java Agent 介绍和实战 。

java agent技术原理及简单实现 。

这篇关于idea插件开发之一起来开发个打印方法入参和返回值的插件吧!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083536

相关文章

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

电脑不小心删除的文件怎么恢复?4个必备恢复方法!

“刚刚在对电脑里的某些垃圾文件进行清理时,我一不小心误删了比较重要的数据。这些误删的数据还有机会恢复吗?希望大家帮帮我,非常感谢!” 在这个数字化飞速发展的时代,电脑早已成为我们日常生活和工作中不可或缺的一部分。然而,就像生活中的小插曲一样,有时我们可能会在不经意间犯下一些小错误,比如不小心删除了重要的文件。 当那份文件消失在眼前,仿佛被时间吞噬,我们不禁会心生焦虑。但别担心,就像每个问题

idea lanyu方式激活

访问http://idea.lanyus.com/这个地址。根据提示将0.0.0.0 account.jetbrains.com添加到hosts文件中,hosts文件在C:\Windows\System32\drivers\etc目录下。点击获得注册码即可。

IDEA配置Tomcat远程调试

因为不想把本地的Tomcat配置改乱或者多人开发项目想测试,本文主要是记录一下,IDEA使用Tomcat远程调试的配置过程,免得一段时间不去配置到时候忘记(毕竟这次是因为忘了,所以才打算记录的…) 首先在catalina.sh添加以下内容 JAVA_OPTS="-Dcom.sun.management.jmxremote=-Dcom.sun.management.jmxremote.port

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

邮件群发推送的方法技巧?有哪些注意事项?

邮件群发推送的策略如何实现?邮件推送怎么评估效果? 电子邮件营销是现代企业进行推广和沟通的重要工具。有效的邮件群发推送不仅能提高客户参与度,还能促进销售增长。AokSend将探讨一些关键的邮件群发推送方法和技巧,以帮助企业优化其邮件营销策略。 邮件群发推送:目标受众 了解他们的需求、兴趣和行为习惯有助于你设计出更具吸引力和相关性的邮件内容。通过收集和分析数据,创建详细的客户画像,可以更精