当我尝试使用动态代理时,我看到以下异常
com.intellij.rt.execution.application.AppMain DynamicProxy.DynamicProxy
Exception in thread "main" java.lang.IllegalArgumentException: interface Interfaces.IPerson is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
at DynamicProxy.Creator.getProxy(Creator.java:18)
at DynamicProxy.DynamicProxy.main(DynamicProxy.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
知道我需要做什么来解决它
如果这是Web应用程序,那么您应该在创建动态代理时使用Web应用程序类加载器。所以,例如,而不是:
Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(),
new Class < ? >[] {MyInterface.class},
new InvocationHandler() {
// (...)
});
尝试:
Proxy.newProxyInstance(
this.getClass().getClassLoader(), // here is the trick
new Class < ? >[] {MyInterface.class},
new InvocationHandler() {
// (...)
});
例如,tomcat类加载器的层次结构(其他Web容器类似)如下:
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
它是webapp类加载器,它包含Web应用程序的/ WEB-INF / classes目录中的类和资源,以及Web应用程序的/ WEB-INF / lib目录下的JAR文件中的类和资源。
当你的 DynamicProxy
试图做 Class.forName(youInterfaceClass.getName())
所结果的 java.lang.Class
instance与创建代理时传递的实例不同。换句话说,你有两个具有相同名称的类对象,代理不确定哪一个是正确的(无论它们是否相同)。
通常,当您尝试代理的接口位于通过两个不同的类加载器(即Tomcat的“common”和“application”)加载的库中时,会发生这种情况。
如果这没有帮助,请在您的应用程序上发布更多信息 - 特别是如果您使用的是任何应用程序服务器,Spring或OSGi。