gpt4 book ai didi

java - 如何修饰现有Java对象的方法?

转载 作者:行者123 更新时间:2023-12-02 09:05:13 25 4
gpt4 key购买 nike

编辑:我已经在 https://stackoverflow.com/a/60235242/3236516 描述了我们的解决方案

我有一个java对象。它是扩展抽象类的许多子类之一的实例。我想修改它的方法之一,以便它在调用原始方法之前运行一些附加代码。我的目标在概念上与 AspectJ 中的切入点相同。

如果我创建原始对象的一些修改版本而不是改变原始对象,那就没问题了。如果解决方案涉及字节码操作也可以。

之前的工作

我考虑过通过 JavaAssist 创建代理。问题是 ProxyFactory 的 create 方法要求我提前知道构造函数的输入类型。我不。我可以创建对象,而无需通过 Objenesis 调用构造函数,但生成的代理对象对于构造函数设置的任何值都将为空值。这意味着只要直接引用构造函数设置的值,我生成的对象的行为就会与原始对象不同。

上下文

我们通过 AWS Kinesis Data Analytics 使用 Flink 来转换一些流数据。我们希望在所有 StreamOperator's 的开头包含一些通用代码。 open() 方法,而无需修改每个运算符。一个用例是确保自定义指标代理在运行运算符(operator)的每个实例上运行。

最佳答案

使用 Byte Buddy,您可以创建包装器或 Java 代理,两者都可以实现此目标。如果您在包装类的构造函数调用方面遇到困难,那么使用 Byte Buddy 也会出现同样的问题,因为任何库都绑定(bind)到 JVM 给出的约束。

要创建 Java 代理,请使用 AgentBuilder。然后,您可以使用 type 步骤指定要拦截的所有类型,例如实现特定接口(interface)或扩展类的所有类型。对于transform,Byte Buddy提供了一个名为Advice的方法装饰API,它允许您添加额外的代码,例如:

class MyAdvice {
@Advice.OnMethodEnter
static void enter() { System.out.println("Hello"); }
}

builder = builder.visit(Advice.to(MyAdvice.class).on(named("foo")));

例如,您可以在指定类型的所有名为“foo”的方法的开头打印 hello world。您可以了解更多关于Java代理的信息in the package documentation for the java.instrument package .

关于java - 如何修饰现有Java对象的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59869270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com