合并 类 与基于 OW2 ASM 事件的方法

Merge classes with OW2 ASM Event based methodology

我正在尝试提出使用 ASM Core 框架(不是 Tree 框架)将两个 classes 合二为一的最佳策略。

由于 ClassReader 和 ClassVisitor 严格绑定到一个 class,你会怎么做?

我已经在官方文档中搜索过,但是所有内容都是使用来自 Tree 模块的 ClassNode 实现的。

假设我们有一个基本通用接口:

public interface CrudDao<T, ID>
{
   T select(final ID id);

   boolean update(final T object);

   boolean insert(final T object);

   boolean delete(final ID id);
}

以及具体的通用实现:

public class MyCrudDao<T, ID> implements CrudDao<T, ID>
{
   @Override
   public T select(final ID id) {
      ...
   }

   @Override
   public boolean update(final T object) {
      ...
   }

   @Override
   public boolean insert(final T object) {
      ...
   }

   @Override
   public boolean delete(final ID id) {
      ...
   }
}

现在我们定义一个抽象 class 扩展 CrudDao,提供额外的功能或覆盖接口方法,同时保持对具体实现无动于衷:

public abstract class ConfigurationDao implements CrudDao<Configuration, String>
{
   public List<Configuration> selectAll() {
      ...
   }

   @Override
   public int count() {
      ...
   }
}

我想通过 ASM 获得的是一个扩展 ConfigurationDao 的新具体 class,它将 CrudDao 接口的方法代理到 MyCrudDao实现(如果尚未覆盖,请参见上面的 count())并且它只是复制抽象的 class 方法。


我实际上是在 Rafael 回答后实现的,但经过简单的基准测试后,与 ByteBuddy 网站上报告的相比,它似乎很慢。

accept() 调用到 toByteArray() 调用(已排除)

我大约需要 25-30 毫秒

如果您只想将两个简单 class 的不相关成员(例如 DTO)复制到同一目标 class,您可以通过创建一个 ClassWriter 并访问两者来实现class您要合并的是:

ClassWriter cw = ...
cw.visit(...);
ClassReader cr1 = new ClassReader("foo.Bar"), cr2 = new ClassReader("qux.Baz");
cr1.accept(new MergeGuard(cw), 0);
cr2.accept(new MergeGuard(cw), 0);
cw.visitEnd();

为了避免你写了两次class文件头,你必须覆盖MergeGuard中的相关方法,需要将ClassVisitor扩展为空而不是委托给超级方法,该方法将在您的 ClassWriter.

上调用这些方法