分为静态和动态代理,动态代理又可以分为JDK 动态代理和cglib两种。
- 静态代理:需要一个接口 A,一个实现了该接口的类 B,然后新创建一个类C,实现接口A,同时C持有一个实现了接口的类B ,那么在实现A接口的方法时候可以调用B实现A接口的方法,在之前或者之后加上自己需要的操作。
使用时创建一个B类对象,传入给C,由C来调用方法。
2.动态代理,静态代理的问题是如果有多个目标类需要加强,那么就要写多个代理类C,非常不方便,所以有了动态代理。
JDK 动态代理:由jdk支持,不需要导入其他依赖包。
2.1 首先 在 Java 动态代理机制中 InvocationHandler 接口和 Proxy 类是核心。 需要接口A,实现类B
2.2 然后需要创建类C ,持有一个需要增强的类,即B, C实现InvocationHandler 接口,只有一个接口需要实现:invoke,
invoke() 方法有下面三个参数:
proxy :动态生成的代理类
method : 与代理类对象调用的方法相对应
args : 当前 method 方法的参数
在这个方法里面调用被代理对象原始的方法,以及需要增强的操作
然后用Proxy .newInstance() 方法获取增强的对象
这个方法一共有 3 个参数:
loader :类加载器,用于加载代理对象。
interfaces : 被代理类实现的一些接口;
h : 实现了 InvocationHandler 接口的对象
用Proxy .newInstance() 方法获取增强的对象转为B类型,由该类型来调用方法。
2.3 cglib实现动态代理,jdk实现的是实现接口的类去增强,而CGlib没有这个要求。其实cglib和jdk代理有点类型,重点是一个接口和类:MethodInterceptor 接口和Enhancer类
2.3.1 首先要导入cglib依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2.3.2 然后有一个需要被代理的对象A,方法a
2.3.3 然后是一个实现MethodInterceptor 接口的类,只有一个方法需要实现 MethodInterceptor
参数: /**
* @param o 代理对象(增强的对象)
* @param method 被拦截的方法(需要增强的方法)
* @param args 方法入参
* @param methodProxy 用于调用原始方法
*/
2.3.4 创建代理类:
Enhancer
这部分类似jdk代理的Proxy.newInstance()