动态代理

动态代理:

  特点:字节码随用随创建,随用随加载

  作用:在不修改源码的基础上,对原有方法进行增强

  分类:基于接口的动态代理

     基于子类的动态代理

基于接口的动态代理:

  涉及到的类:Proxy

  提供者:JDK官方

  如何创建:使用Proxy类中的newProxyInstance方法

  创建要求:要求被代理类(即你需要代理的类)至少实现一个接口

  newProxyInstance参数解释:

    ClassLoader:类加载器

      用于加载代理对象的字节码,和被代理对象使用的是同一个类加载器

    Class【】:字节码数组

      它是为了让代理对象和被代理对象拥有相同的方法

    InvacationHandler:用于提供增强代码

      让我们提供增强的代码。一般给定的是该接口的实现类,但通常情况用匿名内部类实现,但不是必须的。

复制代码
public static void main(String[] args) {
       final Producer producer = new Producer();
       IProducter proxyProducer = (IProducter) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
                producer.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 作用:执行被代理对象的任何接口方法都会经过该方法
                     * 方法参数的含义
                     * @param proxy   代理对象的引用
                     * @param method  当前执行的方法
                     * @param args    当前执行方法所需的参数
                     * @return        和被代理对象方法有相同的返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //提供增强的代码
                        Object returnValue = null;

                        //1.获取方法执行的参数
                        Float money = (Float)args[0];
                        //2.判断当前方法是不是销售
                        if("saleProduct".equals(method.getName())) {
                            returnValue = method.invoke(producer, money*0.8f);
                        }
                        return returnValue;
                    }
                });
        proxyProducer.saleProduct(10000f);
    }
复制代码

基于子类的动态代理: (使用这个代理方式需要引入第三方jar包,cglib)

  涉及到的类:Enhance

  提供者:第三方cglib库

  如何创建:使用Enhance类中的create方法

  创建要求:要求被代理类不可以是最终类

  newProxyInstance参数解释:

    Class:字节码

      用于指定被代理对象的字节码

    Callback:用于提供增强代码

复制代码
public static void main(String[] args) {
        final Producter producter = new Producter();
                Producter cglibProducter = (Producter) Enhancer.create(producter.getClass(),
                new MethodInterceptor() {
                    /**
                     *  作用:执行被代理对象的任何方法,都会经过该方法
                     * @param proxy
                     * @param method
                     * @param args
                     *      以上三个参数和基于接口的动态代理中invoke方法参数一样
                     * @param methodProxy:当前执行方法的代理对象
                     * */
                    @Override
                    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                        //提供增强的代码
                        Object returnValue = null;

                        //1.获取方法执行的参数
                        Float money = (Float) args[0];
                        //2.判断当前方法是不是销售
                        if ("saleProduct".equals(method.getName())) {
                            returnValue = method.invoke(producter, money * 0.8f);
                        }
                        return returnValue;
                    }
                });
        cglibProducter.saleProduct(10000f);
    }
复制代码

 

posted @   CGGirl  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示