• 动态代理的基本理解与基本使用


    • 代理模式

    代理模式,基本都懂吧。就例如我们平时去零售店买电脑。这个零售店其实就是代理商。它并不是直接生产电脑,而是帮一些生产电脑的厂商卖电脑,赚中间价。这就是代理模式。专业一点来说,在这里例子中,电脑厂就是被代理者,是真实对象。零售店就是代理者,是代理对象。代理模式就是,代理对象代理真实对象,达到增强真实对象的目的。

    Java中的代理又分为静态代理与动态代理。

    静态代理:简单地理解,就是有一个类文件来描述。

    动态代理:在内存中形成代理类。

     

    • 动态代理的实现步骤

    (1)代理对象和真实对象实现相同的接口。

    示例:

    // 接口
    
    package com.chichung.proxy;
    
    public interface SaleComputer {
        public String sale(double money);
    }
    // 真实对象实现接口
    
    package com.chichung.proxy;
    
    public class ComputerFactory implements SaleComputer {
        @Override
        public String sale(double money) {
            System.out.println(money+"厂家价");
            return "我是厂家";
        }
    }

    (2)代理对象 = Proxy.newProxyInstance()

    示例:

    package com.chichung.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
        public static void main(String[] args) {
            ComputerFactory cf = new ComputerFactory();
    
            // 代理对象
            SaleComputer proxy_store = (SaleComputer) Proxy.newProxyInstance(cf.getClass().getClassLoader(), cf.getClass().getInterfaces(), new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("hello");
                    return null;
                }
            });

    } }

    Proxy.newProxyInstance()参数解析:

    1.类加载器:真实对象.getClass().getClassLoader()

    2.接口数组:真实对象.getClass().getInterfaces()

    3.处理器:new InvocationHandler(){ ... }

     

    (3)使用代理对象调用方法

    package com.chichung.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
        public static void main(String[] args) {
            ComputerFactory cf = new ComputerFactory();
    
            // 代理对象
            SaleComputer proxy_store = (SaleComputer) Proxy.newProxyInstance(cf.getClass().getClassLoader(), cf.getClass().getInterfaces(), new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("hello");
                    return null;
                }
            });
    
            String str = proxy_store.sale(8000);
            System.out.println(str);
        }
    }

    输出结果:

    hello
    null

    为什么没有真实对象的打印以及返回?不急,看下去。

    先说下invoke方法的几个参数:

    1.proxy:代理对象

    2.method:代理对象调用的方法,被封装为对象。获取方式:method.getName()

    3.args:代理对象调用方法时,传递的实际参数。获取方式:args[0]

     

    (4)增强对象

    先实现一下没有增强对象,输出结果和原来真实对象直接调用方法一样的效果。

    package com.chichung.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
        public static void main(String[] args) {
            ComputerFactory cf = new ComputerFactory();
    
            // 代理对象
            SaleComputer proxy_store = (SaleComputer) Proxy.newProxyInstance(cf.getClass().getClassLoader(), cf.getClass().getInterfaces(), new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object obj = method.invoke(cf, args);    // 使用真实对象调用此方法
                    return obj;
                }
            });
    
            String str = proxy_store.sale(8000);
            System.out.println(str);
        }
    }

    1.增强参数

    package com.chichung.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
        public static void main(String[] args) {
            ComputerFactory cf = new ComputerFactory();
    
            // 代理对象
            SaleComputer proxy_store = (SaleComputer) Proxy.newProxyInstance(cf.getClass().getClassLoader(), cf.getClass().getInterfaces(), new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if (method.getName().equals("sale")){
                        // 增强参数
                        Double money = (Double) args[0];
                        money = money * 1.25;
                        // 使用真实对象调用此方法
                        Object obj = method.invoke(cf, money);
                        return obj;
                    }else {
                        // 使用真实对象调用此方法
                        Object obj = method.invoke(cf, args);
                        return obj;
                    }
                }
            });
    
            String str = proxy_store.sale(8000);
            System.out.println(str);
        }
    }

    输出结果:

    10000.0厂家价
    我是厂家

    2.增强返回值

    package com.chichung.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
        public static void main(String[] args) {
            ComputerFactory cf = new ComputerFactory();
    
            // 代理对象
            SaleComputer proxy_store = (SaleComputer) Proxy.newProxyInstance(cf.getClass().getClassLoader(), cf.getClass().getInterfaces(), new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object obj = method.invoke(cf, args);
                    return obj+",一手货!!!";
                }
            });
    
            String str = proxy_store.sale(8000);
            System.out.println(str);
        }
    }

    输出结果:

    8000.0厂家价
    我是厂家,一手货!!!

    3.增强方法体

    package com.chichung.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest {
        public static void main(String[] args) {
            ComputerFactory cf = new ComputerFactory();
    
            // 代理对象
            SaleComputer proxy_store = (SaleComputer) Proxy.newProxyInstance(cf.getClass().getClassLoader(), cf.getClass().getInterfaces(), new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if (method.getName().equals("sale")){
                        System.out.println("走过路过别错过");
                        Double money = (Double) args[0];
                        money = money * 1.25;
                        // 使用真实对象调用此方法
                        Object obj = method.invoke(cf, money);
                        System.out.println("手快有手慢没");
                        return obj;
                    }else {
                        // 使用真实对象调用此方法
                        Object obj = method.invoke(cf, args);
                        return obj;
                    }
                }
            });
    
            String str = proxy_store.sale(8000);
            System.out.println(str);
        }
    }

    输出结果:

    走过路过别错过
    10000.0厂家价
    手快有手慢没
    我是厂家

  • 相关阅读:
    毕业设计同学们的福利(将word表格导入PowerDesigner中实现快速创建PDM)
    (转载)彻底的理解:WebService到底是什么?
    Aptana常用快捷键总结
    解决nuxt中路由变化后vanlist触底不加载的问题
    vuepropertydecorator的装饰器及其功能(可能不全)
    前端基础复习篇DOM
    Docker如何制作镜像Dockerfile的使用
    接口测试及常用接口测试工具
    SVN快速入门3——整合eclipse(1)
    SVN快速入门1——SVN的安装及常用命令
  • 原文地址:https://www.cnblogs.com/chichung/p/10358444.html
Copyright © 2020-2023  润新知