1 /** 2 * 动态代理: 3 * 特点:字节码随用随创建,随用随加载 4 * 作用:不修改源码的基础上对方法增强 5 * 分类: 6 * 基于接口的动态代理 7 * 基于子类的动态代理 8 * 基于子类的动态代理: 9 * 涉及的类:Enhancer 10 * 提供者:第三方cglib库 11 * 如何创建代理对象: 12 * 使用Enhancer类中的create方法 13 * 创建代理对象的要求: 14 * 被代理类不能是最终类 15 * newProxyInstance方法的参数:在使用代理时需要转换成指定的对象 16 * ClassLoader:类加载器 17 * 他是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法 18 * Callback:用于提供增强的代码 19 * 他是让我们写如何代理。我们一般写一个该接口的实现类,通常情况加都是匿名内部类,但不是必须的。 20 * 此接口的实现类,是谁用谁写。 21 * 我们一般写的都是该接口的子接口实现类,MethodInterceptor 22 */ 23 com.dynamic.cglib.Producer cglibProducer= (com.dynamic.cglib.Producer) Enhancer.create( 24 com.dynamic.cglib.Producer.class, 25 new MethodInterceptor() { 26 /** 27 * 执行被代理对象的任何方法都会经过该方法 28 * @param obj 29 * @param method 30 * @param args 31 * 以上三个参数和基于接口的动态代理中invoke方法的参数是一样的 32 * @param proxy:当前执行方法的代理对象 33 * @return 34 * @throws Throwable 35 */ 36 @Override 37 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 38 Object returnValue=null; 39 Float money=(Float)args[0]; 40 if("saleProduct".equals(method.getName())){ 41 returnValue= method.invoke(producer,money*0.8f); 42 } 43 return returnValue; 44 } 45 } 46 ); 47 cglibProducer.saleProduct(100.0f);
JDK本身提供的动态代理实现
1 /** 2 * 动态代理: 3 * 特点:字节码随用随创建,随用随加载 4 * 作用:不修改源码的基础上对方法增强 5 * 分类: 6 * 基于接口的动态代理 7 * 基于子类的动态代理 8 * 基于接口的动态代理: 9 * 涉及的类:proxy 10 * 提供者:Jdk官方 11 * 如何创建代理对象: 12 * 使用Proxy类中的newProxyInstance方法 13 * 创建代理对象的要求: 14 * 被代理类最少实现一个接口,如果没有则不能使用 15 * newProxyInstance方法的参数:在使用代理时需要转换成指定的对象 16 * ClassLoader:类加载器 17 * 他是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法 18 * Class[]:字节码数组 19 * 它是用于让代理对象和被代理对象有相同方法。固定写法 20 * InvocationHandler:用于提供增强的代码 21 * 他是让我们写如何代理。我们一般写一个该接口的实现类,通常情况加都是匿名内部类,但不是必须的。 22 * 此接口的实现类,是谁用谁写。 23 */ 24 IProducer proxyProducer= (IProducer) Proxy.newProxyInstance( 25 producer.getClass().getClassLoader(), 26 producer.getClass().getInterfaces(), 27 28 new InvocationHandler() { 29 /** 30 * 作用:执行被代理对象的任何接口方法都会经过该方法 31 * @param proxy 代理对象的引用 32 * @param method 当前执行的方法 33 * @param args 当前执行方法所需的参数 34 * @return 和被代理对象有相同返回值 35 * @throws Throwable 36 */ 37 @Override 38 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 39 // 提供增强的代码 40 // 1、获取方法执行的参数 41 Object returnValue=null; 42 Float money=(Float)args[0]; 43 if("saleProduct".equals(method.getName())){ 44 returnValue= method.invoke(producer,money*0.8f); 45 } 46 return returnValue; 47 } 48 } 49 );
JDK和Cglib的区别: