[英]Java dynamic proxies - class implements multiple interfaces
I'm looking at some Java dynamic proxies examples.我正在查看一些 Java 动态代理示例。 A basic one which simply intercepts a method call and add some print-out:一个简单的拦截方法调用并添加一些打印输出的基本方法:
public interface IVehicle {
public void forward();
}
public class Car implements IVehicle {
private String name;
public Car(String name) {this.name = name;}
public void forward() {
System.out.println("Car " + name + " forward");
}
}
public class VehicleHandler implements InvocationHandler {
private Car v;
public VehicleHandler(Car v) {this.v = v;}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
System.out.println("Vehicle Handler: Invoking " + m.getName());
return m.invoke(v, args);
}
}
public class Client {
public static void main(String[] args) {
Car c = new Car("audi");
ClassLoader cl = Car.class.getClassLoader();
IVehicle v = (IVehicle) Proxy.newProxyInstance(cl,
new Class[] {IVehicle.class}, new VehicleHandler(c));
v.forward();
}
}
This example works well and prints out handler and object messages.此示例运行良好,并打印出处理程序和 object 消息。 But then I'm thinking what if the Car class in above example implements multiple interfaces and I call all methods in all implemented interfaces?但后来我在想,如果上面示例中的 Car class 实现了多个接口,我在所有实现的接口中调用所有方法怎么办?
I edited above example to (Changes are surrounded by **):我将上面的示例编辑为(更改由 ** 包围):
public interface IVehicle {
public void forward();
}
**public interface IVehicle2 {
public void forward2();
}**
public class Car implements IVehicle, **IVehicle2** {
private String name;
public Car(String name) {this.name = name;}
public void forward() {
System.out.println("Car " + name + " forward");
}
**public void forward2() {
System.out.println("Car " + name + " forward2");
}**
}
public class VehicleHandler implements InvocationHandler {
private Car v;
public VehicleHandler(Car v) {this.v = v;}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
System.out.println("Vehicle Handler: Invoking " + m.getName());
return m.invoke(v, args);
}
}
public class Client {
public static void main(String[] args) {
Car c = new Car("audi");
ClassLoader cl = Car.class.getClassLoader();
**Car** v = **(Car)** Proxy.newProxyInstance(cl,
new Class[] {IVehicle.class, **IVehicle2.class**}, new VehicleHandler(c));
v.forward();
**v.forward2();**
}
}
I got below error:我收到以下错误:
Exception in thread "main" java.lang.ClassCastException: class com.sun.proxy.$Proxy0 cannot be cast to class Car
My questions are: 1. why do I get above error?我的问题是: 1. 为什么会出现上述错误? 2. How do I correctly do proxy if I want to call both forward()
and forward2()
in above example? 2. 如果我想在上面的例子中同时调用forward()
和forward2()
,我该如何正确地做代理?
Thanks a lot!非常感谢!
You're implementing the Proxy class, ie Car
at compile time.您正在实现代理 class, ie Car
。 The idea of dynamic proxy is to have the 'proxy class' generated at runtime, ie the proxy class implementation at compile time is not needed.动态代理的想法是在运行时生成“代理类”,即不需要在编译时实现代理 class。
In this code snippet在此代码段中
**Car** v = **(Car)** Proxy.newProxyInstance(cl,
new Class[] {IVehicle.class, **IVehicle2.class**}, new VehicleHandler(c));
Have the proxy instance assigned to one of interface that it implements.将代理实例分配给它实现的接口之一。 Based on the interface it's assigned to, the corresponding method can be invoked on the proxy.根据分配给它的接口,可以在代理上调用相应的方法。
If you want a single proxy
that can invoke either of the interface's method, then have a common interface that extends both IVehicle
and IVehicle2
;如果您想要一个可以调用任一接口方法的single proxy
,则拥有一个扩展IVehicle
和IVehicle2
的通用接口; and then use the common interface as the proxy class, ie (assign proxy rcvd. through Proxy.newProxyInstance
to the common interface.然后使用公用接口作为代理class,即(通过Proxy.newProxyInstance
将代理rcvd.赋值给公用接口。
Note: the Car
class can be used for other purposes it may have, including it being the loader class.注意: Car
class 可用于其他用途,包括装载机 class。 When using it as the proxy class, ie**Car** v = **(Car)** Proxy.newProxyInstance
it's not a dynamic proxy class.将其用作代理 class 时, ie**Car** v = **(Car)** Proxy.newProxyInstance
它不是动态代理 class。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.