代理模式
简单来说代理模式就是在不改变原方法(或行为)的前提下对其功能进行扩展。
1、静态代理
//行为接口
public interface IDrive {
public void drive();
}
//目标类型实现了某个行为
public class Driver implements IDrive {
@Override
public void drive() {
System.out.println("驾驶中...");
}
}
如上,驾驶员对象起初只关注驾驶(上车就是干),后来驾驶员意识变强了,驾驶员需要在驾驶前检查车况,但又不能修改原来的代码
//具有同样行为的代理类
public class DriverProxy implements IDrive {
private IDrive targetDriver;
public DriverProxy(IDrive targetDriver) {
this.targetDriver = targetDriver;
}
@Override
public void drive() {
System.out.println("检查车辆。。。"); //添加额外的操作
this.targetDriver.drive(); //原操作不变
System.out.println("驾驶结束。。。");
}
}
//测试一下
public class Main {
public static void main(String[] args) {
Driver driver = new Driver();//驾驶员
DriverProxy proxy = new DriverProxy(driver);//代理驾驶员
proxy.drive(); //执行代理后的驾驶操作
}
}
以上就是一个简单的静态代理模式的实现,需要注意的是代理类和被代理的类要有同样的行为(即实现同样的接口),代理类要包含被代理对象
2、动态代理(JDK代理)
静态代理的缺点就是当接口发生改变时,代理类和被代理类都要改变,此时就可以使用动态代理来避免这种情况
//生成动态代理对象
public class DriverProxy {
public static IDrive createDriverProxy(IDrive targetDriver) {
IDrive proxy = (IDrive) Proxy.newProxyInstance(targetDriver.getClass().getClassLoader(), targetDriver.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("车辆检查。。。");
Object value = method.invoke(targetDriver, args);
System.out.println("驾驶结束。。。");
return value;
}
});
return proxy;
}
}
//测试一下
public class Main {
public static void main(String[] args) {
Driver driver = new Driver();//驾驶员
IDrive driverProxy = DriverProxy.createDriverProxy(driver);
driverProxy.drive();
}
}
注:这两种代理模式都有一个缺点就是目标对象都要实现至少一个行为接口,如果没有的话,可以参考Cglib代理