在运行时用ByteBuddy替换java.io.File

问题描述 投票:1回答:1

在以下情况下如何为给定的Web应用程序(在servlet容器上运行)替换java.io.File

鉴于我有班级class AmazonS3File extends java.io.File

  1. java.io.File替换每个AmazonS3File
  2. 将每个java.io.File替换为AmazonS3File,但在调用来自特定库的情况下,请说com.jetbrains程序包(不确定这在理论上是否可行)

但是,这是我拥有的pseudo代码:

    new AgentBuilder.Default()
            .with(AgentBuilder.Listener.StreamWriting.toSystemOut())
            .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
            .type(ElementMatchers.is(java.io.File.class))
            .transform((builder, typeDescription, classLoader, module) ->
                    new ByteBuddy().redefine(java.io.File.class).constructor(ElementMatchers.anyOf(AmazonS3File.class) /* <-- What to put here?*/))
            .installOnByteBuddyAgent();
    File videoFile = new File(OUTPUT_PATH);
    System.out.println(videoFile.getPath());

[应该放置在ByteBuddy().redefine(java.io.File.class).constructor中以使其加载AmazonS3File的构造函数?

java byte-buddy
1个回答
0
投票
Byte Buddy允许您通过使用Java代理来调整库代码。 Java代理会在加载任何类并使用一个类时收到通知,实际上您可以用new File()替换对new AmazonS3File()的任何调用。为此,您需要转换与此代码内替换相关的包中的所有类。您将为此使用MemberSubstitution

new AgentBuilder.Default() .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) .type(nameStartsWith("pkg.of.library.")) .transform((builder, typeDescription, classLoader, module) -> builder.visit(MemberSubstitution.strict() .constructor(isDeclaredBy(File.class)) .replaceWith(MyFactory.class.getMethod("file", String.class)) .on(any())) .installOnByteBuddyAgent();

为了使这项工作有效,您必须创建一些工厂类MyFactory,该工厂类将返回类型为File的任何实例,例如,如果该文件超出了Java的File,则可以返回您的Amazon文件。

替换基本上说:对于

pgk.of.library的包和子包中的任何类型,请扫描any()方法或构造函数以查找File的构造函数,并将其替换为对MyFactory::file的调用。为此,工厂必须具有与要替换的文件构造函数相同的参数。

© www.soinside.com 2019 - 2024. All rights reserved.