java - 将运行时的 java.io.File 替换为 ByteBuddy
问题描述
如何java.io.File
在以下条件下替换给定的 Web 应用程序(在 servlet 容器上运行)
鉴于我有一堂课class AmazonS3File extends java.io.File
- 将每个替换
java.io.File
为AmazonS3File
- 将 every 替换
java.io.File
为AmazonS3File
但在调用来自特定库的情况下,比如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 File()
您的new AmazonS3File()
. 为此,您需要转换与此代码内替换相关的包中的所有类。您将MemberSubstitution
为此使用 a :
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
.
替换基本上是说:对于pgk.of.library的包和子包中的任何类型,扫描any()
方法或构造函数的构造函数,File
并用调用替换它们MyFactory::file
。为此,工厂必须具有与被替换的文件构造函数相同的参数。
推荐阅读
- java - Hibernate 无法删除子记录
- c# - 反序列化 json 的 C# 最佳对象或类结构
- wordpress - wordpress 更新主题前是否会自动备份旧主题?
- c# - 当一个viewModel依赖多个模型时如何访问数据
- d3.js - d3力图将弧附加到节点中
- php - 如何将已经工作的 jquery ajax 发布请求重用于自动完成功能?
- python - Pip is hanging when I try install anything, for hours. How can I fix this?
- c# - Ninject InSingletonScope 在每个请求中注入单个参数
- r - Shiny Reactive Map Fail - Leaflet map
- javascript - Javascript ES2015 import throws Uncaught SyntaxError: Unexpected token {