Java代理模式整理

2022-02-16  本文已影响0人  ZoranLee
代理模式.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) {}
Class<?> aClass = Class.forName("java.lang.reflect.ProxyGenerator");
        Method generateProxyClass = aClass.getDeclaredMethod("generateProxyClass", String.class, Class[].class);

Class<?> aClass = Class.forName("java.lang.reflect.ProxyGenerator");
        Method generateProxyClass = aClass.getDeclaredMethod("generateProxyClass", String.class, Class.forName("[Ljava.lang.Class;"));
上一篇下一篇

猜你喜欢

热点阅读