[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