上节,我们提到了基于接口的动态代理。
基于接口的动态代理
来完成通过中间代理商,消费者从生产商那里购买产品的功能。
这种动态代理要求第三方jar包的支持。
cglib依赖,版本是2.1_3
基于子类的动态代理
涉及的类:Enhancer
提供者:第三方cglib库
如何创建代理对象
使用Enhancer类中的create方法
创建代理对象的要求
被代理类不能是最终类(最终类无法创建子类)
create方法的参数
- Class:字节码:它是用于指定被代理对象的字节码
- Callback:用于提供增强的代码
它是让我们写如何代理,我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,它不是必须的
我们一般写的都是该接口的子接口实现类:MethodIntercepter(方法拦截)、他是callback的子接口
//模拟一个消费者
public class Client {
public static void main(String[] args) {
//找生产商购买产品。
final Producer producer = new Producer();
//producer.saleProduct(1000);
Producer cglibProducer= (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
/*
* 执行被代理对象的任何方法都会经过该方法
* proxy
* method
* args
* 以上三个参数和基于接口的动态代理中invoke方法的参数是一样。
* methodProxy:当前执行方法的代理对象
*
* */
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//参数1:谁的方法,肯定是被代理对象的方法,当匿名内部类访问外部成员时,要求外部成员时最终的,参数2,要传入的参数
//提供增强的代码
Object returnValue=null;
//1.获取方法执行的参数
Float money=(Float)args[0];
//2.判断当前方法是不是销售
if("saleProduct".equals(method.getName())){
returnValue= method.invoke(producer,money*0.8f);
}
return returnValue;
}
});
cglibProducer.saleProduct(12000f);
}
}
它有一个共同的特点,可以对我们已有的方法进行增强,并且在增强的过程中,可以提供一些我们需要实现的功能。
动态代理的作用
1.连接池:close方法在关闭的时候,不能真正的关闭,而是还回池中,我们可以用动态代理的方式,对connection的close方法进行增强,把他加回到池中去
2.解决全栈中文乱码的request对象的方法增强,我们用装饰者模式实现,用动态代理同样可以实现这样的功能。对getParameter方法进行增强。