动态代理(基于类的动态代理)

感情迁移 提交于 2019-12-05 04:34:53
  1. 特点:字节码随用随创建,随用随加载

  2. 作用:不修改源码的基础上对方法进行增强

  3. 分类:

    1. 基于接口的动态代理

    2. 基于类的动态代理

  4. 基于类的动态代理:

    1. 涉及 的类:Enhance

    2. 提供者:第三方cglib库

    3. 如何创建代理对象:使用Enhance类中的create方法

    4. 创建代理对象的要求:被代理的类不能是最终类

    5. create方法的参数:

      1. class :字节码

        它是同于加载代理对象的字节码的,写的是被代理对象的类加载器。(代理谁就写谁的类加载器)

      2. Callback:用于提供增强的代码

        它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。此接口的实现类谁用谁写。我们一般写的是该接口的子接口实现类:MethodInterceptor

      3. package com.xuefei.cglibProxy;
        
        //生产商
        public class Producer{
            public void saleProduct(float money) {
                System.out.println("拿到钱,给你商品"+money);
            }
        
            public void afterProduct(float money) {
                System.out.println("拿到钱给你售后"+money);
            }
        }
        package com.xuefei.cglibProxy;
        
        import com.xuefei.proxy.IProducer;
        import net.sf.cglib.proxy.Enhancer;
        import net.sf.cglib.proxy.MethodInterceptor;
        import net.sf.cglib.proxy.MethodProxy;
        import java.lang.reflect.InvocationHandler;
        import java.lang.reflect.Method;
        import java.lang.reflect.Proxy;
        
        public class Client {
            public static void main(final String[] args) {
                final Producer producer = new Producer();
        
                Producer producer1 = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
                    /**
                     * 执行被代理对象的任何方法都会经过该方法
                     * @param proxy
                     * @param method
                     * @param args
                     * @param methodProxy
                     * @return
                     * @throws Throwable
                     */
                    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                        //提供增强的代码
                        Object returnValue = null;
                        //获取方法执行的参数
                        Float money = (Float) args[0];
                        //判断当前方法是不是销售
                        if("saleProduct".equals(method.getName())){
                            returnValue = method.invoke(producer,money*0.8f);
                        }
                        return returnValue;
                    }
                });
                producer1.saleProduct(1000f);
            }
        }

         

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!