美文网首页
Java代理模式整理

Java代理模式整理

作者: ZoranLee | 来源:发表于2022-02-16 15:08 被阅读0次
    代理模式.png

    代理模式

    静态代理

    给对象提供代理对象,由代理对象控制对原对象的引用。代理模式如【中介】

    目的

            1、通过代理对象间接访问目标对象,防止直接访目标对象给系统带来的不必要复杂性
            2、通过代理对象对访问进行控制
    

    三个角色

    image.png
    1、抽象角色 【接口】对外提供公共的方法
    2、真实角色 实现抽象角色,实现业务逻辑    
    3、代理角色 实现抽象角色,代理,将统一的流程控制都放到代理角色中
    

    动态代理

        运行时再创建代理类和实例,显然效率更低;使用JDK中Proxy类
    

    示例

    interface Api{
        void test(String a);
    }
    
    class ApiImpl{
      @override
        public void test(String a){
            Sysout("真实实现")
        }
    }
    
    ApiIml api = new ApiImpl();
    Proxy.newProxyInstance(getClass().getClassLoader(),new Class[]{Api.class},new InvocationHandler(){
        public Object invoke(Object proxy,Method method ,Object{
            return  method.invoke(api,args)
    })
    })
    

    Proxy. newproxyInstance探究

    与静态代理不同,这个 Class,不是由具体的.java源文件编译而来,在内存中按照Class格式生成一个Class
    

    1、ProxyGenerator类可以直接调用版本:

    String name= Api.class.getname()+"$Proxy";//生成代理指定接口的c1ass数据
    byte[] bytes =ProxyGenerator, generateProxyclass(name, new Class[]{Api.class}
    Fileoutputstream fos =new Fileoutputstream(lib/+ name+"class");
    os. write(bytes);
    fos. close();
    

    2、ProxyGenerator只能用反射调用静态方法版本

           String name = Api.class.getName() + "$Proxy0";
            //生成代理指定接口的Class数据
            Class<?> aClass = Class.forName("java.lang.reflect.ProxyGenerator");
            Method generateProxyClass = aClass.getDeclaredMethod("generateProxyClass", String.class, Class[].class);
            generateProxyClass.setAccessible(true);
            byte[] bytes = (byte[]) generateProxyClass.invoke(null,name, new Class[]{APi.class});
            FileOutputStream fos = new FileOutputStream("lib/" + name + ".class");
            fos.write(bytes);
            fos.close();
    

    3、查看 Api$Proxy0 类

    1、m3 = Class.forName("com.example.lib.Api").getMethod("test", Class.forName("java.lang.String"));
    
    2、public final void test(String var1) throws  {
            try {
                super.h.invoke(this, m3, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    

    反射调用 ProxyGenerator的静态方法的两种方式

    static byte[] generateProxyClass(String name, Class<?>[] interfaces) {}
    
    • 1、通过类型.class:
    Class<?> aClass = Class.forName("java.lang.reflect.ProxyGenerator");
            Method generateProxyClass = aClass.getDeclaredMethod("generateProxyClass", String.class, Class[].class);
    
    • 2、通过签名:Class.forName("[Ljava.lang.Class;")
    
    Class<?> aClass = Class.forName("java.lang.reflect.ProxyGenerator");
            Method generateProxyClass = aClass.getDeclaredMethod("generateProxyClass", String.class, Class.forName("[Ljava.lang.Class;"));
    

    相关文章

      网友评论

          本文标题:Java代理模式整理

          本文链接:https://www.haomeiwen.com/subject/jvhdlrtx.html