Java代理模式.docx

上传人:太** 文档编号:48684335 上传时间:2022-10-06 格式:DOCX 页数:7 大小:262.79KB
返回 下载 相关 举报
Java代理模式.docx_第1页
第1页 / 共7页
Java代理模式.docx_第2页
第2页 / 共7页
点击查看更多>>
资源描述

《Java代理模式.docx》由会员分享,可在线阅读,更多相关《Java代理模式.docx(7页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、Java代理模式By zvane79 s: blog, 1 .代理模式代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直 接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理模式一般涉及到三个角色:抽象角色:声明真实对象和代理对象的共同接口;代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同 的接口以便在任何时刻都能代替真实对象。同时丁代理对象可以在执行真实对象操作时,附加其他的操作,相当于 对真实对象进行封装。真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。抽

2、象主题类Subjectabstract+ Request ()ProxyRealSubject-realSubject : RealSubject+ Request ()+ Request ()具体主题类代理类,其维护一个具体主题类为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层, 能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上 获得了更大的灵活性。Java动态代理机制以巧妙的方式近乎完美地实践了代理模式的设计理念。2 .静态代理public interfac

3、e Subject void operationl ();void operation2(String arg);public class Subjectlmpl implements Subject public void operationl () System, out. printin (方法调用 1); public void opration2(String arg) System, out .printin (方法调用2 with args + arg); )public class ProxySubject implements Subject private Subject

4、srcObject; / 被代理对象public ProxySubject(Subject srcObject) this.srcObj ect = srcObject; ) public void operationl () System.out.printIn(Proxyer do operationl); srcObject.operationl(); ) public void operation2(String arg) System.out.printin(HProxyer do operation2 with n + arg); srcObject.operation2(arg)

5、; ) ).动态代理动态代理的本质用来实现对目标对象进行增强,最终表现为类,只不过是动态创立子类,不用手工生成子类。动态代理的限制只能在父类方法被调用之前或之后进行增强(功能的修改),不能在中间进行修改,要想在方法调用中增强,需 要ASM(一个Java字节码操作和分析框架)OInterfaceX1. JDK动态代理官方,不能代理类,只能代理接口2. CGLIB动态代理非官方,基于ASM,能代理类和接口,不能代理final类3.1 Jdk动态代理使用首先让我们来了解一下如何使用Java动态代理。具体有如下四步骤:1 .通过实现InvocationHandler接口创立自己的调用处理器,实现接口方

6、法invoke;2 .通过为Proxy类指定ClassLoader对象和一组interface来创立动态代理类;3 .调用动态代理对象的接口方法public class DynamicProxyHandler implements InvocationHandler /代理模式中介绍的RalSubjct对象。private Object srcObject;public DynamicProxyHandler(Object srcObject) this.srcObject = srcObject; )/设tl一个类用于实现工nvocationHandl接口,InvocationHandler

7、是代理实例的调用处理程序实现的接口。/对应invoke参数:/ 1 study .proxy -在其上调用方法的代理实例;/ 2 method -对应于在代理实例上调用的接口方法的Method实例;/ 3args -包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,那么为nullopublic Object invoke(Object proxy, Method method. Object args) throws Throwable System, out .printin ( before method ., *);return method.invoke(srcOb

8、ject, args); ) )public class DynamicProxyDemo public static void main(String args) Subject proxy = (Subject) Proxy.oxyinstance(Subject.class.getClassLoader()z new Class Subject.class , new DynamicProxyHandler(real);subject.operation1 ();) )JDK动态代理的序列图实现动态代理思路如何实现动态代理呢?1 .动态产生Java代码和class.动态生成的代理类必须要

9、继承接口 A,并需要一个handler接口成员变量,该handler接口在外部由用户自己实 现,实现功能的扩展。2 .代理类中的对接口 A方法的调用,即调用handle.invoke接口方法即可。2.4 JDK动态代理实现-类和接口要了解Java动态代理的机制,首先需要了解以下相关的类或接口:2.4.1这是Java动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。清单1. Proxy的静态方法/方法1:该方法用于获取指定代理对象所关联的调用处理器static InvocationHandler getlnvocationHandler(Object proxy)/方

10、法2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象static Class getProxyClass (ClassLoader loader, Class口 interfaces) /方法3:该方法用于判断指定类对象是否是一个动态代理类 static boolean isProxyClass(Class cl)/方法4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例static Object newProxylnstance(ClassLoader loader, Class interfaces, InvocationHandler h) 备注:inte

11、rfaces传入其他接口呢?2.4.2 :这是调用处理器接口,它自定义了一个invoke方法,用于集中处理在动态代理类对象上的方法调用,通常在 该方法中实现对委托类的代理访问。清单2. InvocationHandler的核心方法/该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象/第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行Object invoke(Object proxy, Method method, Object args)每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象(参见

12、Proxy静态方法4的第三个参数)。2.4.3这是类装载器类,负责将类的字节码装载到Java虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。 Proxy静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码 是由JVM在运行时动态生成的而非预存在于任何一个.class文件中。每次生成动态代理类对象时都需要指定一个类装载器对象(参见Proxy静态方法4的第一个参数)思考:为什么要制定classloader参数?2.5 动态代理对象的创立过程1 .生成动态代理类Class2 .通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器Invoc

13、ationHandler接口类型;3 .通过构造函数创立动态代理类实例,构造时调用处理器InvocationHandler对象作为参数被传入。清单3.动态代理对象创立过程/ Tnvocationllandlerlmpl实现了 InvocationHandler接口,并能实现方法调用从代理类到委托类的分派转发/其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用InvocationHandler handler = new InvocationHandlerlmpl;/通过Proxy为包括Interface接口在内的一组接口动态创立代理类的类对象Class clazz = Pr

14、oxy. getProxyClass(classLoader, new ClassL Interface, class, );/通过反射从生成的类对象获得构造函数对象Constructor constructor = clazz. getConstructor(new Class InvocationHandler. class );/通过构造函数对象创立动态代理类实例Interface Proxy = (Interface)constructor, ncwlnstance(new Object handler );关键是Proxy中的newProxylnstance方法public stat

15、ic Object newProxylnstance(ClassLoader loader,Class interfaces,InvocationHandler h)关键点:Proxy. getProxyClasspublic static Class getProxyClass (ClassLoader loader, Class. . interfaces) 关键点:byte proxyClassFile = ProxyGenerator. generateProxyClass(proxyName, interfaces);关键点:private static native Class d

16、efineClassO(ClassLoader loader, String name, byte b, int off, int len);例如:ProxyGenerator是一个代理类字节码生成器,可以看看它的私有类ProxyMethod的私有方法generateMethod defineClassO是一个本地native方法,用来加载类字节码到内存在ClassLoader中也有类似的方法:private native Class defineClassO(String name, byte b, int off, int len,ProtectionDomain pd, boolean

17、verify);private native ClassdefineClassl(String name,byte b, int off, int len,ProtectionDomain pd,ProtectionDomain pd,String source,boolean verify);private native Class defineClass2(String name, java. nio.ByteBuffer b, int off, int len, ProtectionDomain pd, String source, boolean verify);3.6 JDK动态代理

18、内部机制3.6.1 缓存机制3.6.2 接口数目v=655353.6.3 Proxy命名计数规那么代理类名:proxyPkg + “$Proxy + num;3.6.4 多个有相同方法的接口:那么调用传递的一个接口,演示3.6.5 多个非public接口,在不同包下,那么会抛异常。throw newIllegalArgumentException (non-public interfaces from different packages);320321322323324325326327328329330331332333334335336337338339340341多线程并发创立问题创立

19、前,设置一个标记pendingGenerationMarker,表示正在创立,其他线程执行到此wait();唤醒后循环再获取,直到获取成 功,或发现代理类为空,需要创立。/* marks that a particular proxy class is currently being generated */private static Object pendingGenerationMarker = new Object ();3.6.6 持久化动态生成的classSystem. getProperties (). put (sun, misc. ProxyGenerator. saveGe

20、neratedFiles,/, true);见 Openjdk ProxyGenerator 源码:319 public static byte generateProxyClass(final String name,Class interfaces)ProxyGenerator gen = new ProxyGenerator (name, interfaces); final byte classFile = gen. generateClassFile();if (saveGeneratedFiles) java, security. AccessController. doPrivi

21、leged(new java, security. PrivilegedAction() public Void run() try (FileOutputStream file 二new FileOutputStream(dotToSlash(name) + .class);file, write(classFile);file, close(); return null; catch (lOException e) throw new InternalError(I/0 exception saving generated file: + e););)342343return classFile;344结合TMS看一个代理Service实现类源码jdk动态代理源码分析,模拟实现过程CGLIB动态代理分析,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 解决方案

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com