简介
- Proxy代理模式是一种结构型设计模式。通过代理模式可以实现程序之间的解耦,可以解决在直接访问对象时带来的程序之间耦合度增大的问题。
- 按照代理的创建时期,代理类分为两种:
- 静态代理:在编译期,手动创建代理类,而不是由编译器生成代理类。
- 动态代理:在运行期,运用反射机制动态而生成代理类。
- JDK代理基于接口接口
- CGlib代理基于继承
静态代理
- 优点
- 静态代理可以将目标类和目标方法封装起来,有隐蔽的作用。
- 缺点
- 静态代理类只能为特定的接口服务。
- 如想要为多个接口服务则需要建立很多个代理类。
目录结构
- cn.water
- main
- java
- IProducer.java(接口)
- Producer.java(实现类)
- ProxyProducer.java(代理类)
- java
- test
- staticTest.java(测试类)
- main
接口
IProducer.java
1 | package cn.water.StaticProxy; |
实现类
Producer.java
1 | package cn.water.StaticProxy; |
代理类
ProxyProducer.java
1 | package cn.water.StaticProxy; |
测试类
staticTest.java
1 | package cn.water.test; |
动态代理(JDK)
- JDK动态代理基于 Java的反射机制 实现。
- 因为Java的反射机制基于接口,所以目标类一定要有接口。
- 基于JDK技术动态代理类技术核心:Proxy类 和 InvocationHandler接口。(java.lang.reflect)
- Proxy类中定义了生成JDK动态代理类的方法
getProxyClass(ClassLoader loader,Class... interfaces)
,返回class实例代表一个class文件。生成的动态代理类继承Proxy类(重要特性) ,并实现公共接口。 - InvocationHandler接口 是被动态代理类回调的接口,我们所有需要增加的处理逻辑都添加到 invoke方法里面。
- Proxy类中定义了生成JDK动态代理类的方法
- 匿名内部类参数必须为final类型
目录结构
- cn.water
- IProducer.java(接口)
- Producer.java(实现类)
- test
- staticTest.java(测试类)
接口
IProducer.java
1 | package cn.water.DynamicProxy.jdk; |
实现类
Producer.java
1 | package cn.water.DynamicProxy.jdk; |
测试类
staticTest.java
- Proxy.newProxyInstance方法
- 加载器
- 接口
- InvocationHandler接口
- invoke方法
- method:代表方法
- args:参数
- invoke方法
- 匿名内部类只能访问方法内修饰符为final的参数
- 为了保持数据的一致性
1 | package cn.water.test; |
动态代理(cglib)
目录结构
- cn.water
- Producer.java(类)
- test
- staticTest.java(测试类)
实现类
Producer.java
1 | package cn.water.DynamicProxy.cglib; |
测试类
- Enhancer.create方法
- 字节码
- MethodInterceptor接口
- intercept方法
- method:代表方法
- args:参数
- intercept方法
staticTest.java
1 | package cn.water.test; |