java静态代理与动态代理
原文链接:http://www.orlion.ga/207/ 一、代理模式 ????代理模式是经常用到的设计模式,代理模式是给指定对象提供代理对象。由代理对象来控制具体对象的引用。 ? ? 代理模式涉及到的角色: ? ? ? ??抽象主题角色:声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替。
????(设计模式是通用的) ????按照代理创建的时期代理类可以分成两种: ????????静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在????????了。 ????????动态代理:在程序运行时,运用反射机制动态创建而成。 ? ?? 二、静态代理 ????Talk is cheap,show me the code ????首先定义个酒厂的接口: ????WineFactory.java ????package?ml.orlion.proxy;???? ???? ????public?interface?WineFactory?{ ???? ???? public?void?sell(); ????} ????然后再定义一个酒厂类实现这个接口: ????WineFactoryImpl.java ????package?ml.orlion.proxy; ????public?class?WineFactoryImpl?implements?WineFactory{ ???? ???? @Override ???? public?void?sell()?{ ???? System.out.println("卖酒"); ???? } ???? ????} ????然后定义一个代理类,对酒厂进行代理: ????WineFactoryProxy.java ????package?ml.orlion.proxy; ????/** ?????*?代理类 ?????*?对WineFactoryImpl进行代理 ?????*/ ????public?class?WineFactoryProxy?implements?WineFactory{ ???? ???? private?WineFactory?winef; ???? ???? public?WineFactoryProxy(WineFactory?winef){ ???? this.winef?=?winef; ???? } ???? ???? @Override ???? public?void?sell()?{ ???? System.out.println("卖酒之前..."); ???? winef.sell(); ???? System.out.println("卖酒之后..."); ???? } ????} ? 三、动态代理 ????由静态代理的代码可以看到静态代理只能对一个接口进行服务,如果项目中有很多个接口,那么肯定会产生过多的代理。这时候就需要用到动态代理,由一个代理类完成所有的代理功能。动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。 ????JDK动态代理中包含一个InvocationHandler接口和一个Proxy类 ????(1)InvocationHandler接口 ????public?interface?InvocationHandler?{????? ????????public?Object?invoke(Object?proxy,Method?method,Object[]?args)?throws?Throwable;? ????} ????其中Object porxy:是被代理的对象 ????Method method:要调用的方法 ????Object[] args:要调用的方法的参数 ????(2)Proxy类 ????Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法: ????public?static?Object?newProxyInstance(ClassLoader?loader,?Class<?>[]?interfaces,?????InvocationHandler?h)??throws?IllegalArgumentException ????其中ClassLoader loader:是类加载器; ????(在java中主要有三种类加载器: ????????Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的; ????????????Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jrelibext目录中的类;? ????????????AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。?????????? ????) ????Class<?>[] interfaces:得到全部接口; ? ??InvocationHandler h:得到InvocationHandler接口的子类实例; ????code: ?????WineFactory.java和WineFactoryImpl.java和静态代理的代码相同。 ????WineFactoryInvocationHandler.java: ????package?ml.orlion.proxy; ???? ????import?java.lang.reflect.InvocationHandler; ????import?java.lang.reflect.Method; ???? ????/** ?????*?JDK动态代理类 ?????*?对WineFactoryImpl进行代理 ?????*/ ????public?class?WineFactoryInvocationHandler?implements?InvocationHandler{ ???? ???? private?Object?target; ???? ???? @Override ???? public?Object?invoke(Object?porxy,?Method?m,?Object[]?args)?throws?Throwable?{ ???? ???? Object?result?=?null; ???? ???? beforeMethod(); ???? //?执行 ???? result?=?m.invoke(target,?args); ???? ???? afterMethod(); ???? return?result; ???? } ???? ???? public?void?beforeMethod(){ ???? System.out.println("卖酒之前..."); ???? } ???? ???? public?void?afterMethod(){ ???? System.out.println("卖酒之后..."); ???? } ???? ???? public?Object?getTarget()?{ ???? return?target; ???? } ???? ???? public?void?setTarget(Object?target)?{ ???? this.target?=?target; ???? } ????} ????测试: ????//?产生一个被代理对象 ????WineFactory?wf?=?new?WineFactoryImpl(); ????//?将被代理对象交给InvocationHandler ????WineFactoryInvocationHandler?wfih?=?new?WineFactoryInvocationHandler(); ????wfih.setTarget(wf); ????//?根据被代理对象产生一个代理 ????WineFactory?wfp?=?(WineFactory)Proxy.newProxyInstance(wf.getClass().getClassLoader(),?wf.getClass().getInterfaces(),?wfih); ????wfp.sell(); ???? ????除了JDK动态代理外还有一种cglib动态代理,具体可参考文章(本文参考):http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |