一,动态代理
什么是动态代理?
动态代理就是在程序运行期间,创建目标对象的代理对象,并对目标对象中的方法进行功能性的增强的一种技术,有两种实现方式。
jdk代理:
1,定义一个类去实现InvocationHandler接口,重写invoke方法。
2,定义一个Object的属性,用来指向我们需要代理的对象。
3,定义构造方法,入参为需要代理的对象。
4,定义一个方法(getProxy),去获取代理对象的类加载器,以及实现的所有接口。再通过Proxy.NewProxyInstance。NewProxyInstance中需要传入三个参数,分别是类加载器,所有的接口,以及拦截器,由于我们是实现的InvocationHandler,所以这个类的本身就相当于一个拦截器,直接传入this本身即可。
5,根据业务编写invoke方法。invoke方法中入参的参数有:proxy代理对象,methods调用的方法,和args。我们通过反射methods.invoke()可以激活此方法。
使用:
首先new出来我们的目标对象,然后new出来我们的动态代理类,将目标对象传入其中。
再调用我们的getProxy方法,强转成我们的目标对象的接口对象。最后再通过我们生成的代理对象去调用我们想要调用的方法。
由于jdk代理是通过目标类实现接口创建代理对象的,所以jdk代理只能代理实现了接口的对象。
cglib代理:
cglib代理是通过创建目标类的子类来创建代理对象的。所以说即时一个类没有实现任何接口我们同样也可以代理。
1,导入cglib的jar包
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2,定义一个类去实现我们的MethodInterceptor接口,重写我们的interceptor方法。
3,定义一个Object的属性指向我们需要被代理的对象。
4,编写构造方法入参为我们的目标类,赋值给第三步定义的Object的属性。
5,定义一个获取代理类的方法(getProxy),在此方法中先New出Enhancer方法。通过enhancer去调用setSuperClass设置代理类的父类。再通过enhancer去调用callBack方法设置回调,需传入一个CallBack对象,由于我们实现了这个MethodInterceptor接口,所以我们在这里直接传入this即可。再通过enhancer去调用create()创建一个代理对象。最后返回这个代理对象出去。
6,根据业务场景编写interceptor方法。interceptor方法中有method属性,通过反射去激活,objects代表方法中的属性列表。
调用:
和jdk代理类似,唯一区别是由于我们的cglib是通过生成目标类的子类来实现的,所以我们在转换时,要注意是转换成我们的代理类,而不是代理类的接口。