定义
本质是对目标方法的增强,允许代理类在执行目标方法时,做些自己的事来增强目标方法。
静态代理
如果知道被代理类的具体职责,可以使用静态代理。如果不清楚被代理类是谁,只能只用动态代理。这是静态代理和动态代理的区别,即是否清楚被代理对象是谁。
UML
代理类和被代理类同时实现Movable接口,此时,除了可以增强Tank对象外,还允许对代理对象做增强,实现代理和代理之间的互相嵌套。是不是很像装饰者模式?其实有些设计模式本身就没有清晰的边界。
代码
UML图已经很清晰了,写点核心代码,体会这个UML的精髓。
new Proxy(new Proxy(new Tank()));
动态代理
动态代理分JDK动态代理和CGLib动态代理,都比较简单,不再累赘。学习动态代理的时候,建议将asm生成的代理类保存到文件中,设置以下参数:
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
总结
静态代理在知道被代理对象的时候可以用,简单。动态代理有更大的灵活性,允许对任何类做增强。
JDK动态代理和CGLib动态代理底层都是实用asm动态字节码技术,JDK动态代理中,被代理的类需要有继承的接口。CGLib动态代理不需要有任何父类或实现任何接口,简单。
Spring的AOP中,看情况选择动态代理方式:
- 默认使用 JDK 动态代理,这样便可以代理所有的接口类型(interface)
- Spring AOP也支持CGLIB的代理方式。如果我们被代理对象没有实现任何接口或者实现的接口都是空接口,则是CGLIB