代理模式介绍

代理模式是一种设计模式,用于在客户端和目标对象间创建一个代理对象,控制对目标对象的访问。静态代理在编译时已确定代理关系,需要手动创建代理类。动态代理则在运行时动态生成,如JDK动态代理和CGLib动态代理,前者基于反射,后者基于字节码生成。代理模式常用于功能增强、远程代理、防火墙代理和保护对象访问控制。
摘要由CSDN通过智能技术生成

什么是代理模式

对一个对象提供一个代理对象,使用代理对象控制对原对象的引用。

使用代理模式目的

透明的控制对象的访问,代理模式的作用是隐藏对象的复杂性,控制对对象的访问,并在必要时增加一些额外的功能。

代理模式的分类

 静态代理

在编译期间就已经确定了代理关系,也就是说代理类和被代理类的关系在程序运行之前就已经确定了。静态代理需要自己定义一个代理类,这个代理类需要实现和被代理类一样的接口,然后在代理类中调用被代理类的方法,并且可以在方法前后添加一些额外的逻辑。

动态代理

在运行期间动态生成代理类,也就是说代理类和被代理类的关系是在程序运行时动态生成的。

类是如何动态生成的

Java 虚拟机类加载过程主要分为五个阶段:加载、验证、准备、解析、初始化。

加载阶段中,关于获取二进制字节流,有以下几种方式:

1)从本地获取字节码:Java虚拟机可以从本地文件系统加载类的字节码文件。

2)从网络中获取二进制字节流:Java虚拟机也可以从网络中加载类的字节码数据。使用类加载器的getResourceAsStream()方法,通过指定URL的方式来获取InputStram,然后通过读取InputStream获取字节数据。

3)运行时就算生成:这种场景使用最多的是动态代理技术,在java.lang.reflect.Proxy类中,就是用了ProxyGenerator.generateproxyClass来为特定接口生成形式为“*$Proxy”的代理类的二进制字节流。

所以动态代理就是想办法,根据接口或目标对象,计算出代理类的字节码,然后加载到JVM中使用

动态代理分类

1)JDK动态代理

2)CGLib动态代理

两种动态代理技术的区别

JDK动态代理和CGLib动态代理是Java语言中实现动态代理的两种方式。区别如下:

1)基于的技术不同:JDK动态代理是基于Java反射机制实现的,而CGLib动态代理则是使用字节码生成技术实现的。

2)被代理类的要求不同:JDK动态代理只能代理实现了接口的类,而CGLib动态代理可以代理没有实现接口的类。

3)代理性能不同:JDK动态代理生成的代理类性能相对较低,因为它是基于反射实现的;而CGLib动态代理生成的代理类性能相对较高,因为它基于字节码生成技术(ASM)实现的。

4)代理方式不同:JDK动态代理是基于接口实现的,因此代理类必须实现被代理接口;CGLib动态代理是基于集成实现的,因此代理类继承被代理类。

综上所述,JDK动态代理适合代理接口方法,而CGLib动态代理适合代理普通类方法。

静态代理、动态代理的区别

1)实现方式不同:静态代理在编译期就已经确定了代理对象的类型,代理类需要手动编写。动态代理是在运行时动态生成代理对象,代理类不需要手动编写,而是由框架自动生成。

2)适用范围不同:静态代理只适用于代理对象类型固定、接口较少的情况下。因为每增加一个被代理的接口,就需要编写一个新的代理类。动态代理则可以代理任意的接口,无需编写新的代理类,因此更加灵活。

3)性能表现不同:由于静态代理在编译期就已经确定代理对象的类型,因此在运行时执行效率较高。而动态代理在运行时需要进行额外的代理对象生成,方法调用转发等操作,因此会存在一定的性能损失。

总的来说,静态代理适用于代理对象类型固定、接口较少、性能要求较高的情况。而动态代理则适用于代理对象类型不固定、接口较多、灵活性要求较高的情况。

代理模式结构图

1)抽象主题(Subject): 定义了真实主题和代理主题的共同接口

2)真实主题(Real Subject):定义了代理所代表对象,是代理所要代理的对象

3)代理(Proxy): 提供了与真实主题相同的接口,同时还负责创建和删除真实主题对象,使得客户端不直接与真实主题进行交互

4)客户端(Client): 通过代理访问真实对象

代理模式优点

1)代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用

2)代理对象可以扩展目标对象的功能

3)代理模式将客户端与目标对象分离,在一定程度上降低了系统的耦合度

代理模式缺点

增加了系统的复杂度

使用场景

1)功能增强

当需要对一个对象的访问提供一些额外操作时,可以使用代理模式

2)远程代理

实际上,RPC框架也可以看作是一种远程代理模式,通过远程代理,将网络通信、数据遍解码等细节隐藏起来,客户端使用RPC服务的时候,就像使用本地函数一样,无需了解跟服务器交互的细节。

3)防火墙代理

当你将浏览器配置成使用代理功能时,防火墙就将你的浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把它转给你的浏览器。

4)保护代理

控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代理模式是一种常见的设计模式,它允许你创建一个代理对象,代表另一个对象的接口。代理模式可以用于很多不同的场景,例如实现延迟加载、权限控制、远程调用等等。代理模式可以分为静态代理和动态代理两种。静态代理需要手动编写代理类,而动态代理则可以在运行时动态地生成代理类。在Java中,动态代理有两种实现方式:基于接口的动态代理和基于子类的动态代理(CGLIB)。基于接口的动态代理需要目标类实现一个或多个接口,而基于子类的动态代理则需要目标类没有被final修饰。 以下是一个基于接口的动态代理的例子,假设我们有一个UserService接口和一个UserServiceImpl实现类: ```python from abc import ABCMeta, abstractmethod import dynamicproxy class UserService(metaclass=ABCMeta): @abstractmethod def save(self, username): pass class UserServiceImpl(UserService): def save(self, username): print("Save user: {}".format(username)) # 使用动态代理 user_service_proxy = dynamicproxy.DynamicProxy(UserServiceImpl()) user_service_proxy.save("Tom") ``` 在这个例子中,我们使用Python的abc模块定义了一个UserService接口,其中包含了一个save方法。然后我们实现了一个UserServiceImpl类来实现这个接口。最后,我们使用了动态代理来代理UserServiceImpl类,并调用了save方法。 动态代理的实现可以参考Python的第三方库dynamicproxy。具体来说,我们可以定义一个DynamicProxy类来实现动态代理,如下所示: ```python class DynamicProxy: def __init__(self, target): self.target = target def __getattr__(self, name): # 在此处可以添加代理逻辑 return getattr(self.target, name) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值