簡體   English   中英

在運行時用 ByteBuddy 替換 java.io.File

[英]Replace java.io.File on runtime with ByteBuddy

在以下情況下,如何為給定的 Web 應用程序(在 servlet 容器上運行)替換java.io.File

鑒於我有一個class AmazonS3File extends java.io.File

  1. AmazonS3File替換每個java.io.File
  2. AmazonS3File替換每個java.io.File但在調用來自特定庫的條件下,比如com.jetbrains包(不確定這在理論上是否可行)

但是,這是我的代碼:

    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的構造函數?

Byte Buddy 允許您通過例如使用 Java 代理來調整庫代碼。 Java 代理會在加載和使用任何類時收到通知,您確實可以用new AmazonS3File()替換對new File()的任何調用。 為此,您需要轉換與此代碼內替換相關的包中的所有類。 您將為此使用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的調用。 為此,工廠必須具有與被替換的文件構造函數相同的參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM