Java 动态代理原理

date
Nov 12, 2021
slug
java-dynamic-proxy
status
Published
tags
Java
summary
Java 动态代理的原理
type
Post

代理模式

代理模式类图:
notion image
被代理类和代理类都实现同一个接口,通过在代理类对象中注入一个被代理对象,通过调用代理对象的方法,在其方法中间接调用被代理对象,从而实现代理的作用。
代理模式要点:
  • 代理和被代理类实现同一接口
  • 代理对象中持有被代理对象的实例
 

静态代理

静态代理就是代理模式的具体实现。首先定义一个接口
接口的实现类,也是被代理类
再定义一个代理类,同样实现接口:
具体使用代理类:
 

为什么要有动态代理?

静态代理不足在于,增强代码只能对固定的某一个类起作用,如对 Student 类增强,那么就要编写针对 Student 类的接口 Person 的实现类,在实现类中编写增强代码。
如果增强代码是统计方法执行时间,那么就需要在各种各样不同的类的接口上,重复做上述的事情:编写实现类,类中实现接口方法,编写增强代码等。
而动态代理就是解决一套增强代码,用在各种不同类之上的方式。
 

动态代理 JDK 实现

如果被代理类有接口,则可以是要用 JDK 的方式。JDK 提供了一组编写动态代理的基类。
Person 类不变:
编写 java.lang.reflect.InvocationHandler 接口的实现类,在这个接口中只有一个方法需要实现,就是 invoke 方法,在这个类中编写增强代码,未来代理功能就是通过调用这里实现的代理效果。
类中的泛型 T 已经证明这个代码可以用在不同的类上。
使用 java.lang.reflect.Proxy 根据 InvocationHandler 来生成动态代理类,接着调用动态代理类:
 

动态代理 CGLib 实现

JDK 动态代理是基于接口的,要求被代理类需要实现接口。如果其没有接口,可以使用 CGLib 方式,这种方式基于继承。
一个具体类,也就是被代理类:
 
编写实现了 org.springframework.cglib.proxy.MethodInterceptor 接口的类,是一个方法拦截器类,即拦截被代理方法,在其中做增强:
使用 org.springframework.cglib.proxy.Enhancer 基于被代理类构造出代理对象
enhancer 对象的创建和使用跟前面 Proxy.newProxyInstance 的目的是一样的。
 
参考:
 
 

© 菜皮 2020 - 2024