字节码编程bytebuddy之通过Advice动态修改方法参数值

写在前面

本文看下如何通过bytebuddy的advice切面技术来动态修改方法入参值。

1:程序

首先定义premain:

package com.dahuyou.change.method.param;

//import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;
import java.lang.instrument.Instrumentation;

public class MyPreMain {

    public static void premain(String agentArgs, Instrumentation instrumentation) {
        System.out.println("MyPreMain.premain agentArgs is: " + agentArgs);

        AgentBuilder agentBuilder = new AgentBuilder.Default();

        AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {
            builder = builder.visit(
                    Advice.to(MyByteBuddyAdvice.class)
                            .on(ElementMatchers.named("newSelectorManager")));
/*
        AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {
            builder = builder.visit(
                    Advice.to(MyByteBuddyAdvice.class)
                            .on(ElementMatchers.isMethod()
                                    .and(ElementMatchers.any())
                                    .and(ElementMatchers.not(ElementMatchers.nameStartsWith("main")))));
*/
            return builder;
        };

        agentBuilder = agentBuilder.type(ElementMatchers.nameStartsWith("com.dahuyou.change.method.param")).transform(transformer).asDecorator();

        //监听
        AgentBuilder.Listener listener = new AgentBuilder.Listener() {
            @Override
            public void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {

            }

            @Override
            public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {
                System.out.println("onTransformation:" + typeDescription);
            }

            @Override
            public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {

            }

            @Override
            public void onError(String s, ClassLoader classLoader, JavaModule javaModule, boolean b, Throwable throwable) {

            }

            @Override
            public void onComplete(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {

            }

        };
        // 将bytebuddy的插桩逻辑安装到instrument
        agentBuilder.with(listener).installOn(instrumentation);
    }

    /**
     * 有public static void premain(String agentArgs, Instrumentation instrumentation)这个方法,本方法不会被调用
     * @param agentArgs
     */
    public static void premain(String agentArgs) {}
}

重点是代码Advice.to(MyByteBuddyAdvice.class)指定了切面类MyByteBuddyAdvice,在方法进入和方法退出时分别调用对应注解的方法,源码如下:

package com.dahuyou.change.method.param;

import net.bytebuddy.asm.Advice;

public class MyByteBuddyAdvice {

    @Advice.OnMethodEnter()
    public static void enter(@Advice.Argument(value=2, readOnly=false) int param2,
                             @Advice.Origin("#t") String className,
                             @Advice.Origin("#m") String methodName) {
//        System.out.println("MyByteBuddyAdvice.enter className " + className + ", methodName is: " + methodName);
        System.out.println("MyByteBuddyAdvice.enter param2 " + param2);
        param2 = 9090;
    }

    @Advice.OnMethodExit()
    public static void exit(@Advice.Origin("#t") String className, @Advice.Origin("#m") String methodName) {
//        System.out.println("MyByteBuddyAdvice.exit className " + className + ", methodName is: " + methodName);
    }
}

注解@Advice.OnMethodEnter()标注的方法在方法执行前调用,注解@Advice.OnMethodExit()标注的方法在方法退出前调用。@Advice.Argument(value=2, readOnly=false) int param2注解用于获取方法的第三个参数(要保证有第三个参数,并且类型是int,如果不是,我也没验证会发生什么,但肯定程序就跑不了了)#t#m分别获取类名称和方法名称。

在enter方法中修改第三个参数的值param2 = 9090

测试类:

//
//  ========================================================================
//  Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package com.dahuyou.change.method.param;

public class ServerConnector {

    public static void main(String[] args) {
        ServerConnector serverConnector = new ServerConnector();
        serverConnector.newSelectorManager(null, null, 9);
    }

    protected void newSelectorManager(Object executor, Object scheduler, int selectors) {
        showSelector(selectors);
    }

    private void showSelector(int selectors) {
        System.out.println("selector is: " + selectors);
    }
}

打包:
在这里插入图片描述
配置Javaagent:
在这里插入图片描述
运行:
在这里插入图片描述

写在后面

参考文章列表

ByteBuddy(五)—拦截方法参数、方法返回和实例变量 。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java web从入门到精通 (第 2版)中文电子版

前言 《Java Web从入门到精通(第2版)》共分21章,包括Java Web应用开发概述、HTML与CSS网页开发基础、JavaScript脚本语言、搭建开发环境、JavaBean技术、Servlet技术、过滤器和监听器、Hibernate高级应用、Java Web的数据库操作、EL&#xf…

Linux 上 TTY 的起源

注:机翻,未校对。 What is a TTY on Linux? (and How to Use the tty Command) What does the tty command do? It prints the name of the terminal you’re using. TTY stands for “teletypewriter.” What’s the story behind the name of the co…

每日一题,力扣leetcode Hot100之49. 字母异位词分组

该题用哈希表解答,具有统一特征的作为哈希表的键名,然后满足要求的作为值 解法一: 我们将每个字符串进行排序,如果排序后的结果相同,则可以认为是字母异位词,我们将排序后的结果作为哈希表的key&#xff…

智能听诊器:宠物健康监测的革新者

宠物健康护理领域迎来了一项激动人心的技术革新——智能听诊器。这款创新设备以其卓越的精确度和用户友好的操作,为宠物主人提供了一种全新的健康监测方法。 使用智能听诊器时,只需将其放置在宠物身上,它便能立即捕捉到宠物胸腔的微小振动。…

S274多功能可编程RTU在智慧水务远程水质检测系统中的应用案例

钡铼第四代RTU S274作为一款多功能可编程的无线工业物联网数据监测采集控制短信报警终端,为智慧水务领域提供了强大的技术支持和解决方案。 技术概述与特点 钡铼S274基于UCOSII嵌入式实时操作系统,支持多种通信协议包括短信和MQTT,能够接入…

2024嘶吼网络安全产业图谱(高清完整版)

在数字化和智能化浪潮的推动下,网络安全产业正处于一个快速变革的时期。从传统的防御手段和被动的威胁应对,到如今主动预防和智能检测技术的普及,网络安全领域的焦点和需求正不断演进。为了更好的理解当前网络安全产业现状和未来发展方向&…

jeecgboot项目不知道什么原因启动出来8080端口后就不下去了,要等上10多分钟才出来接口地址等正常情况

因为这个项目license问题无法开源,更多技术支持与服务请加入我的知识星球。 1、项目中途不知道什么原因,就出现下面情况 具体如下: 2024-07-15 15:08:15.767 [main] [34mINFO [0;39m [36mliquibase.changelog:30[0;39m - Reading from jeec…

【LeetCode】十七、并查集

文章目录 1、并查集Union Find2、并查集find的优化:路径压缩 Quick find3、并查集union的优化:权重标记 1、并查集Union Find 并查集,一种树形的数据结构,处理不相交的两个集合的合并与查询问题。 【参考:&#x1f4…

优化 Java 数据结构选择与使用,提升程序性能与可维护性

优化 Java 数据结构选择与使用,提升程序性能与可维护性 引言 在软件开发中,数据结构的选择是影响程序性能、内存使用以及代码可维护性的关键因素之一。Java 作为一门广泛使用的编程语言,提供了丰富的内置数据结构,如数组、链表、…

python用selenium网页模拟时xpath无法定位元素解决方法2

有时我们在使用python selenium xpath时,无法定位元素,红字显示no such element。上一篇文章写了1种情况,是包含iframe的,详见https://blog.csdn.net/Sixth5/article/details/140342929。 本篇写第2种情况,就是xpath定…

嵌入式人工智能(9-基于树莓派4B的PWM-LED呼吸灯)

1、PWM简介 (1)、什么是PWM 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是在具有惯性的系统中利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制…

Open3D 最小二乘法拟合点云平面

目录 一、概述 1.1最小二乘法原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2matplotlib可视化 3.3平面拟合方程 前期试读,后续会将博客加入该专栏,欢迎订阅 Open3D点云算法与点云深度学习…

【内网穿透】打洞笔记

文章目录 前言原理阐述公网sshfrp转发服务 实现前提第一步:第二步第三步第四步 补充第五步(希望隧道一直开着)sftp传数据(嫌云服务器上的网太慢) 前言 租了一个云服务器,想用vscode的ssh远程连接&#xff…

Java面试八股之简述redis常见的性能问题和解决方案

简述redis常见的性能问题和解决方案 Redis作为一款高性能的键值存储系统,虽然设计用于提供低延迟的读写操作,但在特定场景下仍可能出现性能瓶颈。下面列出了一些常见的Redis性能问题及其解决方案: 常见性能问题 内存使用过高 Redis是内存…

支付宝低代码搭建电商小程序,无需编程,可视化操作

大家好,我是小悟 在数字化浪潮的推动下,为了更快速、高效地搭建电商小程序,支付宝低代码平台凭借其独特优势,为商家提供了便捷的解决方案。 支付宝低代码平台犹如一座精心打造的智慧工坊,让电商小程序的搭建变得轻而易…

生成树(STP)协议

一、生成树的技术背景 1、交换机单线路上链,存在单点故障,上行线路及设备都不具备冗余性,一旦链路或上行设备发生故障,网络将面临断网。 总结:以下网络不够健壮,不具备冗余性。 2、因此引入如下网络拓扑结构: 上述冗余拓扑能够解决单点故障问题,但同时冗拓扑也带来了…

多级表头固定列问题

父级的width,是需要固定的列的width的总和 参考: el-table 多级表头下对应列的固定

国产麒麟、uos在线编辑word文件并控制编辑区域(局部编辑)

windows系统也适用,该插件可同时支持windows和国产系统 在实际项目开发中,以下场景可能会用到Word局部编辑功能: 合同审批公文流转策划设计报告汇签单招投标(标书文件)其他,有模板且需要不同人员协作编辑…

OpenGL笔记十三之Uniform向量数据传输、使用glUniform3f和glUniform3fv

OpenGL笔记十三之Uniform向量数据传输、使用glUniform3f和glUniform3fv —— 2024-07-14 晚上 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记十三之Uniform向量数据传输、使用glUniform3f和glUniform3fv1.glUniform3f1.1.运行1.2.vs1.3.fs1.4.shader.…