JAVA 代理模式
简而言之,代理是一种通过创建代理对象的方式,从而实现对被代理对象实现功能增强的一种方式,JAVA 中有静态和动态两种代理,动态代理又可以分为_基于接口的动态代理_(JDK 实现)和_基于子类的动态代理_(cglib 实现),这里我们讲解基于子类的动态代理
基于子类的动态代理(cglib 实现的动态代理)
使用代理的好处就是在不修改原代码的基础上可以实现对原方法的增强,使用JDK
官方的动态代理主要是依靠Proxy
类,这种方法实现的动态代理要求被代理类_至少实现一个接口_,没有实现接口的类是不能被代理的
那么没有实现接口或者不需要实现接口的类,我们怎么对它进行代理呢?
通过引入第三方cglib
库,我们可以实现基于子类的动态代理,使用cglib
实现的动态代理也有一个约束条件,就是被代理类不能是最终类
使用cglib
实现的动态代理核心是Enhancer
类,其实实现的过程和JDK
实现动态代理的过程极其类似
导入 jar 包
我是用的是maven
工程,所以第一步是要导入cglib
的 jar 包,当然手动导入也没有问题,pom.xml
文件配置如下:
1 | <dependency> |
编写被代理类
我这里被代理类主要就实现一个卖东西的功能,之后我们会通过代理类对被代理类中的方法进行增强操作:
1 | package com.lmh.cglib; |
编写代理类(这里也是一个测试类)
这一步是整个过程的关键,代理类的实现要通过Enhancer
类,我们需要通过Enhancer
类中的create
方法创建一个代理对象,具体实现方法如下,作用是给售价打八折,后面我会详细的解释各部分的功能
1 | package com.lmh.cglib; |
这里我们可以看到,enhancerProducer
就是我们创建的代理对象,这个对象可以执行被代理类中所有的方法,并且我们可以在代理对象中对被代理类的方法进行增强,这里使用了强转,因为create
方法的返回值是Object
类型的对象
create
方法有两个参数,分别是Class type
和Callback callback
,其中Class type
是值被代理类的字节码文件,这是固定的,因为有了被代理类的字节码后,就相当于可以获取被代理类的全部信息;Callback callback
是用于提供增强代码的,一般都是写一个接口的实现,通常情况下都是匿名内部类,这里我们一般不适用Callback
接口,而是使用它的子接口实现类MethodInterceptor
MethodInterceptor
接口需要重写intercept
方法,intercept
方法中的内容即为对被代理类的增强,该方法有四个参数:Object o
、Method method
、Object[] objects
和MethodProxy methodProxy
Object o
参数,是一个代理对象的引用,Method method
是当前执行,即被拦截的被代理类方法,Objects[] objects
是当前执行方法所用的参数,索引顺序即为方法定义时参数的顺序,MethodProxy methodProxy
指的是当前执行的方法的代理对象
通过向上述代码一样编写,我们就可以实现对被代理类功能的增强!