代理模式
代理模式属于结构型模式,一个类代表另一个类的功能,创建具有现有对象的对象,以便向外界提供功能接口,为其他对象提供一种代理以控制对这个对象的访问。
也就是增强和控制访问的作用(不能直接访问该类,但是又需要调用其中的方法并拓展)
优点:是可以增强目标对象的功能,降低代码耦合度,扩展性好。
缺点:是在客户端和目标对象之间增加代理对象会导致请求处理速度变慢,增加系统复杂度。
- Spring 利用动态代理实现 AOP,如果 Bean 实现了接口就使用 JDK 代理,否则使用 CGLib 代理。
静态代理
- 代理对象持有被代理对象的引用,调用代理对象方法时也会调用被代理对象的方法,但是会在被代理对象方法的前后增加其他逻辑。需要手动完成,在程序运行前就已经存在代理类的字节码文件,代理类和被代理类的关系在运行前就已经确定了。
- 缺点是一个代理类只能为一个目标服务,如果要服务多种类型会增加工作量。
动态代理
- 动态代理在程序运行时通过反射创建具体的代理类,代理类和被代理类的关系在运行前是不确定的。动态代理的适用性更强,主要分为 JDK 动态代理和 CGLib 动态代理。
JDK 动态代理
- 通过 Proxy 类的 newInstance 方法获取一个动态代理对象,需要传入三个参数,被代理对象的类加载器、被代理对象实现的接口,以及一个 InvocationHandler 调用处理器来指明具体的逻辑,相比静态代理的优势是接口中声明的所有方法都被转移到 InvocationHandler 的 invoke 方法集中处理。
CGLib 动态代理
- JDK 动态代理要求实现被代理对象的接口,而 CGLib 要求继承被代理对象,如果一个类是 final 类则不能使用 CGLib 代理。
- 两种代理都在运行期生成字节码,JDK 动态代理直接写字节码,而 CGLib 动态代理使用 ASM 框架写字节码,ASM 的目的是生成、转换和分析以字节数组表示的已编译 Java 类。
- JDK 动态代理调用代理方法通过反射机制实现,而 GCLib 动态代理通过 FastClass 机制直接调用方法,它为代理类和被代理类各生成一个类,该类为代理类和被代理类的方法分配一个 int 参数,调用方法时可以直接定位,因此调用效率更高。
代理模式(Proxy Pattern)总结 - 我吃印度飞饼的文章 - 知乎
JDK动态代理(介绍理解,如何实现)
CGLib动态代理