java在另一个包中委托接口的方法时,如何使委托类成为非公共类?
在我的库中,我正在生成客户端提供的接口的实现(用库中的自定义指令注释)。我使用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
,但我对字节库还不够熟悉,所以还不知道辅助类型机制是否适合这种情况
有没有一种方法可以生成运行时代理来实现桥接方法,这样我就可以隐藏委托实现
# 1 楼答案
委托类型需要对调用它的类可见。你只有两种可能:
在运行时,对拦截器进行子类化,并确保所有拦截器方法都是公共的。默认情况下,Byte Buddy生成一个公共子类:
上面的类型将是公共的,这样您现在就可以委托给这个实例,即使
ImplDelegate
是包私有的。但是请注意,这只会影响编译时的可见性,在运行时,ImplDelegate
的子类对任何类型都是可见的。(然而,构造函数仍然是包私有的,即使对于子类也是如此。)