设计模式学习-代理模式

    xiaoxiao2021-03-25  76

    代理模式是java中间件中很常用的一种模式,这篇文章是通过慕课网上的代理模式讲解的一个总结。

    定义:为其他对象提供一种代理用来控制这个对象访问,起到中介作用要么去掉某些功能要么增加额外服务

    分类:

    远程代理:不同地址空间对象,提供局域网代表对象虚拟代理:资源消耗大,或复杂对象延迟加载,真正需要时才加载保护代理:控制对象权限智能引用代理:提供目标对象额外服务(日志、权限、事务管理)

    静态代理:

    代理和被代理对象是确定的,实现相同接口或者继承相同抽象类,继承实现会使得代理类会无限膨胀,所以推荐用聚合

    动态代理:

    JDK动态代理

    事务处理器InvocationHandler

    动态代理类:

    运行时生成的类class实现一组接口interface实现动态代理类必须实现InvocationHandler接口

    实现步骤:

    创建类实现InvocationHandler接口中的Invoke方法创建被代理的类及接口调用Proxy静态方法创建代理类 Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHanderl h) 通过代理类调用方法

    JDK动态代理只能代理实现了接口的类

    CGLIB动态代理针对类实现代理,对指定目标类产生子类,通过方法拦截父类方法调用

    CGLIB动态代理

    实现MethodInterceptor中方法 Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy);

    通过Proxy的newInstance返回代理对象:

    声明源码,动态产生代理 String methodString = ""; for (Method m : infce.getMethods()) { methodString += " @Override\n" + " public void " + m.getName() + "() {\n" + " try { " + " Method m = " + infce.getName() + ".class.getMethod(" +"\"" + m.getName() + "\""+ ");\n" + " h.invoke(this,m);\n" + " }\n" + " catch(Exception e){\n" + " e.printStackTrace();\n" + " }\n" + " }\n" + "}"; } String source = "package design.jdkproxy;\n" + "import design.jdkproxy.InvocationHandler;\n" + "import java.lang.reflect.Method;\n" + "public class $Proxy0 implements " + infce.getName() + "{\n" + " private InvocationHandler h;\n" + "\n" + " public $Proxy0(InvocationHandler h){\n" + " super();\n" + " this.h = h;\n" + " }\n" + methodString + "\n"; String fileName = System.getProperty("user.dir") + "/src/main/java/design/jdkproxy/$Proxy0.java"; File file = new File(fileName); FileUtils.writeStringToFile(file, source); 编译源码,产生代理类 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null,null); Iterable units = fileManager.getJavaFileObjects(fileName); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, units); task.call(); fileManager.close(); 将这个类load到内存,产生新的对象 ClassLoader cl = ClassLoader.getSystemClassLoader(); Class c = cl.loadClass("design.jdkproxy.$Proxy0"); 返回代理对象 Constructor ct = c.getConstructor(InvocationHandler.class); return ct.newInstance(h);
    转载请注明原文地址: https://ju.6miu.com/read-37662.html

    最新回复(0)