Java代理模式整理
2022-02-16 本文已影响0人
ZoranLee
代理模式.png
代理模式
静态代理
给对象提供代理对象,由代理对象控制对原对象的引用。代理模式如【中介】
目的
1、通过代理对象间接访问目标对象,防止直接访目标对象给系统带来的不必要复杂性
2、通过代理对象对访问进行控制
三个角色
image.png1、抽象角色 【接口】对外提供公共的方法
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;"));