合并 类 与基于 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
.
上调用这些方法
我正在尝试提出使用 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()
调用(已排除)
如果您只想将两个简单 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
.