【发布时间】:2017-02-21 20:36:25
【问题描述】:
在我的库中,我正在生成客户端提供的接口的实现(使用库中的自定义指令进行注释)。我使用MethodDelegation 拦截接口方法并将它们转发到库包中定义的委托类的实例:
package library.pkg;
class ImplBase { }
public class ImplDelegate {
final ImplContext context;
ImplDelegate(ImplContext ctx) {
this.context = ctx;
}
public void impl(
@CustomName String name,
@CustomTags String[] tags,
@AllArguments Object[] args) {
// do things here
}
}
static <T> T implClient(Class<T> clientType) {
MethodDelegation delegation = MethodDelegation
.to(new ImplDelegate(new ImplContext(clientType)))
.filter(not(isDeclaredBy(Object.class)))
.appendParameterBinder(ParameterBinders.CustomTags.binder)
.appendParameterBinder(ParameterBinders.CustomName.binder);
Class<? extends ImplBase> implClass =
new ByteBuddy()
.subclass(ImplBase.class)
.name(String.format("%s$Impl$%d", clientType.getName(), id++))
.implement(clientType)
.method(isDeclaredBy(clientType).and(isVirtual()).and(returns(VOID)))
.intercept(delegation)
.make()
.load(clientType.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
return clientType.cast(implClass.newInstance());
}
// In client code, get an instance of the interface and use it.
package client.pkg;
interface Client {
void operationA(String p1, long p2);
void operationB(String... p1);
}
Client client = implClient(Client.class);
client.operationA("A", 1);
这可行,但它将ImplDelegate 公开为库中的公共类型;我宁愿让它保持包私有。这样做的一种方法是在运行时在库包中生成ImplDelegate 的公共子类,它使用公共桥接方法代理所有包私有方法并将其用作委托。我看过TypeProxy,但我对 ByteBuddy 还不够熟悉,还不知道辅助类型机制是否适合这个。
有没有办法生成运行时代理,以某种方式实现桥接方法,以便我可以隐藏委托实现?
【问题讨论】:
标签: java byte-buddy