[Java] Proxy在实际编码中的应用
- - ITeye博客Java的类反射机制中包括了动态代理技术,其核心设计围绕InvocationHandler接口和Proxy类. 我们定义一个Car接口,然后实现它:. 一般情况下,我们可以这样使用它:. 如果我们要用Proxy来做,首先需要一个实现了InvocationHandler的代理类:. 执行程序,同样会输出BigCar.
public interface Car {
public void description();
}
public class BigCar implements Car {
public void description() {
System.out.println("BigCar");
}
}
Car car = new BigCar(); car.description();
BigCar
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class CarProxy implements InvocationHandler {
private Object delegate;
public Object newInstance(Object delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
method.invoke(delegate, args);
return null;
}
}
CarProxy cp = new CarProxy(); Car car = (Car) cp.newInstance(BigCar.class.newInstance()); car.description();
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class CarProxy implements InvocationHandler {
private Object delegate;
public Object newInstance(Object delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println("before method: " + method.getName());
try {
method.invoke(delegate, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
System.out.println("after method: " + method.getName());
}
return null;
}
}
CarProxy cp = new CarProxy(); Car car = (Car) cp.newInstance(BigCar.class.newInstance()); car.description();
before method: description BigCar after method: description
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class CarProxy implements InvocationHandler {
private Object delegate;
public Object newInstance(Object delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) {
if (method.getName().equals("description")) {
System.out.println("Caught by proxy.");
}
return null;
}
}
CarProxy cp = new CarProxy(); Car car = (Car) cp.newInstance(BigCar.class.newInstance()); car.description();
Caught by proxy.
private Object delegate;
public interface Flavor {
public void taste();
}
public class Spicy implements Flavor {
public void taste() {
System.out.println("Spicy");
}
}
public interface Color {
public void show();
}
public class Red implements Color {
public void show() {
System.out.println("Red");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MultipleProxy implements InvocationHandler {
private Class[] interfaces;
private Object[] delegates;
public MultipleProxy(Class[] interfaces, Object[] delegates) {
this.interfaces = (Class[]) interfaces.clone();
this.delegates = (Object[]) delegates.clone();
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Class declaringClass = m.getDeclaringClass();
for (int i = 0; i < interfaces.length; i++) {
if (declaringClass.isAssignableFrom(interfaces[i])) {
try {
return m.invoke(delegates[i], args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
return methodNotFound(proxy, m, args);
}
protected Object methodNotFound(Object proxy, Method m,
Object[] args)
throws Throwable {
throw new InternalError("unexpected method dispatched: " + m);
}
}
Class[] proxyInterfaces = new Class[]{Color.class, Flavor.class};
Object obj = Proxy.newProxyInstance(Color.class.getClassLoader(),
proxyInterfaces,
new MultipleProxy(proxyInterfaces, new Object[]{new Red(), new Spicy()}));
Color color = (Color) obj;
color.show();
Flavor flavor = (Flavor) obj;
flavor.taste();
Red Spicy