JDK代理和CGLIB代理
完全转载自https://juejin.cn/post/7011357346018361375 ,以防丢失故作备份 。
一、什么是代理模式 #
代理模式(Proxy Pattern)给某一个对象提供一个代理,并由代理对象控制原对象的引用。代理对象在客户端和目标对象之间起到中介作用。
代理模式是常用的结构型设计模式之一,当直接访问某些对象存在问题时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。代理模式属于结构型设计模式,属于GOF23种设计模式之一。
代理模式可以分为静态代理和动态代理两种类型,而动态代理中又分为JDK动态代理和CGLIB代理两种。
代理模式包含如下角色:
- Subject (抽象主题角色) 抽象主题角色声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题 的地方都可以使用代理主题。客户端需要针对抽象主题角色进行编程。
- Proxy (代理主题角色) 代理主题角色内部包含对真实主题的引用,从而可以在任何时候操作真实主题对象。 在代理主题角色中提供一个与真实主题角色相同的接口,以便在任何时候都可以替代真实 主体。代理主题角色还可以控制对真实主题的使用,负责在需要的时候创建和删除真实主 题对象,并对真实主题对象的使用加以约束。代理角色通常在客户端调用所引用的真实主 题操作之前或之后还需要执行其他操作,而不仅仅是单纯的调用真实主题对象中的操作。
- RealSubject (真实主题 角色) 真实主题角色定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业 务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的方法。
代理模式的优点 #
- 代理模式能将代理对象与真实被调用的目标对象分离。
- 一定程度上降低了系统的耦合度,扩展性好。
- 可以起到保护目标对象的作用。
- 可以对目标对象的功能增强。
代理模式的缺点 #
- 代理模式会造成系统设计中类的数量增加。
- 在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。
二、JDK动态代理 #
在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler
(Interface)、另一个则是 Proxy
(Class),这一个类和接口是实现我们动态代理所必须用到的。
InvocationHandler #
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。
InvocationHandler这个接口的唯一一个方法 invoke 方法:
java
复制代码Object invoke(Object proxy, Method method, Object[] args) throws Throwable
这个方法一共接受三个参数,那么这三个参数分别代表如下:
- proxy:指代JDK动态生成的最终代理对象
- method:指代的是我们所要调用真实对象的某个方法的Method对象
- args:指代的是调用真实对象某个方法时接受的参数
Proxy #
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是newProxyInstance 这个方法:
...