前言:代理模式就是提供了一个实际对象的代理,以便更好的控制实际对象。而动态代理则是更进一步,利用反射机制更方便的的实现代理模式这种思想。
场景:如果想要买一个CPU,那么就要知道英特尔和A厂CPU的价格。那么可以这么实现:
/**
* CPU 接口类
*/
public interface CPU {
void name();
void price();
}
/**
* CPU - Intel
*/
public class IntelI7 implements CPU {
@Override
public void name() {
System.out.println("Intel i7 10700K");
}
@Override
public void price() {
System.out.println("¥2800");
}
}
/**
* CPU - AMD
*/
public class AMDR7 implements CPU {
@Override
public void name() {
System.out.println("AMD R7 5800X");
}
@Override
public void price() {
System.out.println("¥3200");
}
}
/**
* CPU代理类
*/
public class CPUProxy implements CPU {
private CPU cpu;
public CPUProxy(CPU cpu) {
this.cpu = cpu;
}
@Override
public void name() {
System.out.println("before name log");
cpu.name();
}
@Override
public void price() {
System.out.println("before price log");
cpu.price();
}
}
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
CPUProxy proxy = new CPUProxy(new AMDR7());
proxy.name();
proxy.price();
}
同样的还用另一种方法实现动态代理,那就是通过InvocationHandler
来实现:
public class CPUInvokeProxy implements InvocationHandler {
private CPU cpu;
public CPUInvokeProxy() {
}
/**
* 实例化对象的时候绑定需要代理的类
*
* @param cpu
*/
public CPUInvokeProxy(CPU cpu) {
this.cpu = cpu;
}
/**
* 通过方法绑定需要代理的类
*
* @param cpu
* @return
*/
public CPU bind(CPU cpu) {
this.cpu = cpu;
return (CPU) Proxy.newProxyInstance(this.cpu.getClass().getClassLoader(), this.cpu.getClass().getInterfaces(), this);
}
public CPU getProxy() {
return (CPU) Proxy.newProxyInstance(this.cpu.getClass().getClassLoader(), this.cpu.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before CPU`s method invoked ...");
return method.invoke(this.cpu, args);
}
}
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
CPU cpu = new CPUInvokeProxy().bind(new IntelI7());
cpu.name();
cpu.price();
CPU cpu1 = new CPUInvokeProxy(new AMDR7()).getProxy();
cpu1.name();
cpu1.price();
}