目录
[一. 前言](#一. 前言)
[二. 实现](#二. 实现)
[三. 静态代理和动态代理](#三. 静态代理和动态代理)
一. 前言
代理模式(Proxy Pattern),为某个对象提供一种代理以控制对对象的访问。即客户端可通过代理对象间接访问目标对象,同时可限制、增强、修改目标对象的一些特性。访问者不想或者不能直接访问目标对象,代理对象作为目标对象和访问者之间的中介。
使用场景:
远程代理(Remote Proxy) :控制对远程对象(不同地址空间)的访问,它负责将请求及其参数进行编码,并向不同地址空间中的对象发送已经编码的请求。
虚拟代理(Virtual Proxy) :根据需要创建开销很大的对象,它可以缓存实体的附加信息,以便延迟对它的访问,例如在网站加载一个很大的图片时,不能马上完成,可以用虚拟代理缓存图片的大小信息,然后生成一张临时图片代替原始图片。
保护代理(Protection Proxy) :按权限控制对象的访问,它负责检查调用者是否具有实现一个请求所必须的访问权限。
智能代理(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作: 记录对象的引用次数;当第一次引用一个持久化对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。
二. 实现
抽象目标(Subject):定义目标对象的行为。
具体目标(RealSubject):实现抽象目标,实现其具体行为。
代理类(Proxy):实现抽象目标,拥有对具体目标的引用,同时可对目标对象进行增强处理。
java
public interface Subject {
/**
* 定义目标类行为
*/
void behavior();
}
java
public class RealSubject implements Subject {
@Override
public void behavior() {
System.out.println("我是真实对象");
}
}
java
public class Proxy implements Subject {
private Subject targetObject = new TargetSubject();
@Override
public void behavior() {
System.out.println("前置加强处理");
this.targetObject.behavior();
System.out.println("后置加强处理");
}
}
java
public class Client {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.behavior();
}
}
java
前置加强处理
我是真实对象
后置加强处理
三. 静态代理和动态代理
代理模式共有两类三种实现方式,即静态代理和动态代理,同时动态代理可以使用 jdk 动态代理和 cglib 动态代理实现。
静态代理:代理类在编译期生成。
动态代理:代理类在运行期生成。
jdk 动态代理:
Java.lang.reflect 包中的 proxy 类和 InvocationHandler 接口提供了生成代理类的功能。jdk 动态代理有一个限制,那就是代理目标类必须实现一个或多个接口。
cglib 动态代理:
cglib 是一个强大的高性能代码生成包,它可以在运行时扩展 java 类或实现 java 接口。被广泛应用于许多 aop 框架,如 spring aop 和 dynaop。其底层使用一个小而快的字节码处理框架 ASM,通过 asm 来转换字节码并生成类。
jdk 动态代理与 cglib 动态代理区别:
使用 jdk 代理的目标类必须实现一个或多个接口。
使用 cglib 代理的目标类则无需实现,但其不能被 final 修饰,因为其运用了继承关系。
jdk 1.8 以后 jdk 动态代理效率要高于 cglib。