我正在尝试将一些C#
代码移植到Java
中,但是代理实现方面遇到了问题。
我有这个类:
public class Comic
{
public int ComicID;
private List<Volume> _volumes;
public List<Volume> GetVolumes()
{
return _volumes;
}
public void SetVolumes(List<Volume> volumes)
{
_volumes = volumes;
}
}
我正在尝试为该实体的特定方法调用添加拦截器,但我还需要访问它的字段,因为我将使用它们。
在查找如何在Java中实现代理时,我得到了这个:
public void Load(Class<?> type)
{
// - type is a Comic.class
ClassLoader appLoader = this.getClass().getClassLoader();
MyProxyHandler proxyHandler = new MyProxyHandler();
Object proxy = Proxy.newProxyInstance(appLoader, new Class[] { ComicInterface.class }, proxyHandler);
}
问题是,类型是动态的,所以我不知道将会是什么,而且我不想让代码要求拥有所有东西的接口,所以我查了一下如何 构建动态接口:
public class InterfaceLoader extends ClassLoader
{
public InterfaceLoader(ClassLoader loader)
{
super(loader);
}
public Class<?> GetInterface(Class<?> type) throws Exception
{
String interfaceName = type.getName() + "$Proxy";
Class<?> interfaceType = null;
interfaceType = findLoadedClass(interfaceName);
if (interfaceType != null) { return interfaceType; }
// - According to the link
byte[] classData = new InterfaceBuilder().BuildInterface(interfaceName, type.getDeclaredMethods());
return defineClass(interfaceName, classBytes, 0, classBytes.length);
}
}
然后我会与代理一起使用它:
public void Load(Class<?> type)
{
// - type is a Comic.class
ClassLoader appLoader = this.getClass().getClassLoader();
InterfaceLoader loader = new InterfaceLoader(appLoader);
Class<?> dynamicInterface = loader.GetInterface(type);
// - dynamicInterface on debug is "console.Comic$Proxy", seems fine
MyProxyHandler proxyHandler = new MyProxyHandler();
Object proxy = Proxy.newProxyInstance(appLoader, new Class[] { dynamicInterface }, proxyHandler);
}
我得到的异常是
java.lang.IllegalArgumentException: interface console.Comic$Proxy is not visible from class loader
我查找了该异常但只找到两种解决方案,一是确保名称不与任何类型冲突(我确定没有),另一个是使用
this.getClass().getClassLoader()
而非type.getClass().getClassLoader()
(同样的错误)。我错在哪了?还有另一个问题,如何获取“原始”的对象,以便可以从字段(例如
ComicID
)中获取/设置值?使用上述代理方法,我可以拦截方法,但无法访问其字段。我已经阅读了这里的信息来获取InvocationHandler,但我不知道如何从处理程序获取对象,我也找不到相关的示例。