动态代理 静态代理
概述;
代理人帮被代理人做某件事,同时添加自己的操作
代理行为,被代理人事件前后执行的操作
聚合相比于继承的好处在于 可以公用 不会被某一类所限制
类图:
静态代理
代理对象/被代理对象 共同实现接口 代理类中聚合被代理对象实现的接口
可以实现代理间灵活的嵌套
jdk动态代理
目的:
分离代理行为与被代理对象 可以代理各种类型 不在被聚合的接口所限制
类图:
两段:生成代理类的过程 调用的过程
用法
通过 Proxy.newProxyInstance 自动生成
可以通过方法:
System.getProperties().put(“jdk.proxy.ProxyGenerator.saveGeneratedFiles”,”true”); 保存 自动生成的代理文件 $Proxy0.Class 文件 查看
通过反编译可以看出
$Proxy0 继承 Proxy 实现了 被代理类接口
其中自动生成了 实现接口中的方法

h 为 父类Proxy中的 InvocationHandler 执行了 invoke 方法
当新建代理对象 执行了 接口中的方法

实际是 执行的自动生成的代理类中的 接口方法
又自动调用了 InvocationHandler 中的 invoke 方法
所以执行了 重写方法中的 invoke 方法
Object o = method.invoke(m, args);
method 为接口中的方法,m 为引用(被代理对象)
传入那个引用 就执行哪个引用实现的接口方法。
public class Tank implements Movable {/*** 模拟坦克移动了一段儿时间*/@Overridepublic void move() {System.out.println("Tank moving claclacla...");try {Thread.sleep(new Random().nextInt(10000));} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {Tank tank = new Tank();//reflection 通过二进制字节码分析类的属性和方法Movable m = (Movable)Proxy.newProxyInstance(Tank.class.getClassLoader(),new Class[]{Movable.class}, //tank.class.getInterfaces()new LogHander(tank));m.move();}}class LogHander implements InvocationHandler {Tank tank;public LogHander(Tank tank) {this.tank = tank;}//getClass.getMethods[]@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("method " + method.getName() + " start..");Object o = method.invoke(tank, args);System.out.println("method " + method.getName() + " end!");return o;}}interface Movable {void move();}
jdk动态代理
最底层用的是 ObjectWeb包下的 ASM
ASM可以直接造作二进制字节码文件
cglib动态代理
不需要被代理类实现接口
代码举例
动态代理嵌套
动态代理没有聚合被代理类实现的接口 如何实现代理嵌套
动态代理的灵活性 只需要 在重写执行器方法时 将需要生成的代理类执行的方法切入就行
