代理模式是一种设计模式,提供了对目标对象额外的访问方式及通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下提供额外的功能操作,扩展目标对象的功能
举例说明:
在租房的时候,有的人会通过房东直租,有的人会通过中介租房,中介一般是会提供一些额外的服务。这里的中介就相当于是代理
动态代理:就是在我们程序运行的时候呢,我们可以动态的来创建我们这个代理对象,我们就不需要提前知道我们这个类的具体信息
动态代理实现方式
JDK实现:JDK Proxy基于反射
第三方类实现:CGLIB基于ASM(一个Java字节码操作框架)
基于接口的jdk动态代理实现步骤
- 定义目标类即被代理的类
- 通过实现InvocationHandler接口来自定义自己的InvocationHandler重写invoke方法,在此方法中定义增强逻辑
- 通过Proxy.newProxyInstance(原目标类类加载器,原目标类接口数组,代理类)方法获得代理对象
- 通过代理对象调用目标方法
基于类的CGLIB动态代理实现步骤
- 引入CGLIB的相关依赖
- 定义目标类及被代理的类
- 创建代理类实现CGLIB的MethodInterceptor接口并重写intercept方法,在此方法中定义增强逻辑
- 使用Enhancer类创建的代理对象设置目标类,回调对象等参数
- 调用代理对象的方法,实现代理行为
JDK Proxy与CGLIB的区别
基于接口VS基于类:
- Jdk Proxy只能代理接口类型,通过实现指定接口并生成代理对象来实现代理功能
- CGLIB可以代理普通的类,他通过继承目标类,并在子类中重写方法来实现代理
实现方式:
- JDK Proxy是基于反射机制实现的,他利用JAVA的反射API动态生成代理对象
- CGLIB使用了字节码生成库,直接操作字节码生成代理类。相比于jdk代理的反射,调用CGLIB的方法调用更快速
性能:
- 由于CDLIB是直接对字节码进行操作,所以在创建和执行代理对象时,通常比jdk代理更快速
- JDK Proxy的性能略低,因为它涉及到反射调用的开销,JAVA 8版本已经优化性能与CGLIB差不多
库依赖:
- JDK Proxy是JAVA标准库的一部分,无需额外的依赖
- CGLIB需要引入相关的第三方库