- 浏览: 154891 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
追求幸福:
每增加一个新的activity, 都要为这个activity指 ...
关于setContentView -
雨过天晴0521:
感谢第一位留言的网友, 我会坚持下去
ADB push的用法 -
小光棍:
謝謝。整理出來的東西真有用!!
ADB push的用法
JAVA设计模式:代理(Proxy)
代理模式对其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
笔者总结代理模式的两个核心内容:一是隔离访问者对被访问对象之间的直接交互,对被访问对象的一切操作通过代理对象执行,这一点与装饰模式和外观模式类似;另一方面代理对象对被代理对象的业务逻辑作出修改,可以增加、屏蔽部分业务逻辑,这一点是装饰和外观模式所不允许的。
代理模式应用最多的场景是对业务访问进行前置和后置处理。举一个唱歌的例子,原来有一个歌手唱歌的对象,现在歌手要登台演出,唱歌前后要加上报幕和谢幕的动作。歌手不是每次都是登台演出,所以直接修改唱歌的类加上报幕和谢幕的操作显然不合适,这里使用代理模式来解决这个问题:
上面的方式很好的解决了登台演出的问题,但这样解决方法必须在设计阶段完成,具有很大的局限性。JDK提供了动态创建代理的工具,使得我们在运行时可以生成对象的代理,与上面的代码不同,这里就是我们常说的动态代理:
通过这种方式,被代理的对象(Fancy)可以在运行时动态改变,需要控制的接口(Sing接口)可以在运行时改变,控制的方式(DynamicProxy类)也可以动态改变,从而实现了非常灵活的动态代理关系。
更多精彩原创文章请关注笔者的原创博客:http://www.coolfancy.com
============================================
How can I make my dynamic proxy throw checked exceptions?
You can use a dynamic proxy. As long as the checked exceptions are part of the interface you can throw the checked exceptions from the invocation handler. Otherwise this is illegal and will create an UndeclaredThrowableException that wraps the thrown checked exception.
Output:
With an undeclared checked exception for interface A:
A dynamic proxy can throw checked exception if the exception is declared in the signature of the method of the interface it is proxying. From the Sun's Dynamic Proxy reference:
If an exception is thrown by the invoke method, it will be also thrown by the method invocation on the proxy instance.
The exception's type must be assignable to either any of the exception types declared in the signature of the interface method or to the unchecked exception types java.lang.RuntimeException or java.lang.Error.
If a checked exception is thrown by invoke that is not assignable to any of the exception types declared in the throws clause of the interface method, then an UndeclaredThrowableException will be thrown by the method invocation on the proxy instance. The UndeclaredThrowableException will be constructed with the exception that was thrown by the invoke method.
====================================================
Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
动态代理的定义:一个动态代理类在运行期implements一组interface,使得interface实现类的方法调用被分派至其他的类(另外的interface实现类或者任意的类)的方法。讲得更通俗一些,要了解动态代理,我们就要知道什么东西动态了,代理了什么?首先,一个Proxy代理了一组interface的方法。注意,代理的是interface,而不是Class,也不是abstract Class;其次,Proxy具有的型别由绑定的interface所决定的,动态就体现在此。
阅读上述代码:上述就是一个简单的动态代理的例子。我们可以看到Dynamic Proxy并没有实现Resource这个接口,但是包含了Resource接口实现类的实例;在Dynamic Proxy的create方法中,通过调用Proxy.newProxyInstance创建一个Proxy,并将该Proxy与Resource接口绑定,最后将Proxy显式类型转换成Resource接口类型并返回,这样调用者就可以通过Proxy调用interface定义的方法了;由于 Proxy与Resource接口绑定了,对Resource接口的方法调用,都会交由Proxy的invoke方法去处理。而invoke方法会根据不同的方法,或给以全新的实现,或直接将方法调用交给Proxy中包含的Resource接口实现类的实例去处理。综合上面所说的,作为一个Dynamic Proxy,它必须满足以下三个条件:
1、实现了InvocationHandler接口,实现接口中定义的invoke方法;
2、包含接口实现类的实例;
3、通过Proxy.newProxyInstance方法实现Proxy与接口之间的绑定。
代理模式对其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
笔者总结代理模式的两个核心内容:一是隔离访问者对被访问对象之间的直接交互,对被访问对象的一切操作通过代理对象执行,这一点与装饰模式和外观模式类似;另一方面代理对象对被代理对象的业务逻辑作出修改,可以增加、屏蔽部分业务逻辑,这一点是装饰和外观模式所不允许的。
代理模式应用最多的场景是对业务访问进行前置和后置处理。举一个唱歌的例子,原来有一个歌手唱歌的对象,现在歌手要登台演出,唱歌前后要加上报幕和谢幕的动作。歌手不是每次都是登台演出,所以直接修改唱歌的类加上报幕和谢幕的操作显然不合适,这里使用代理模式来解决这个问题:
interface Sing { void sing(); } class Fancy implements Sing { @Override void sing() { System.out.println("唱歌!"); } }
public class FancyProxy implements Sing { Sing singger; public FancyProxy(Sing singger) { this.singger = singger; } @Override public void sing() { //报幕 baoMu(); //唱歌 singger.sing(); //谢幕 xieMu(); } }
上面的方式很好的解决了登台演出的问题,但这样解决方法必须在设计阶段完成,具有很大的局限性。JDK提供了动态创建代理的工具,使得我们在运行时可以生成对象的代理,与上面的代码不同,这里就是我们常说的动态代理:
class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling " + method); method.invoke(target, args); System.out.println("after calling " + method); return null; } static void main(String[] args) { Fancy fancy = new Fancy(); // 在这里指定被代理类 InvocationHandler handler = new DynamicProxy(fancy); // 初始化代理类 Class cls = fancy.getClass(); Sing sing = (Sing) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), handler); sing.sing(); } }
通过这种方式,被代理的对象(Fancy)可以在运行时动态改变,需要控制的接口(Sing接口)可以在运行时改变,控制的方式(DynamicProxy类)也可以动态改变,从而实现了非常灵活的动态代理关系。
更多精彩原创文章请关注笔者的原创博客:http://www.coolfancy.com
============================================
How can I make my dynamic proxy throw checked exceptions?
You can use a dynamic proxy. As long as the checked exceptions are part of the interface you can throw the checked exceptions from the invocation handler. Otherwise this is illegal and will create an UndeclaredThrowableException that wraps the thrown checked exception.
interface A{ void x() throws IOException; }
A proxy = (A) newProxyInstance(classLoader, new Class<?>[]{A.class}, new InvocationHandler() { @Override public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { throw new IOException(); } } ); proxy.x();
Output:
Exception in thread "main" java.io.IOException at X$1.invoke(X.java:19) at $Proxy0.x(Unknown Source) at X.main(X.java:22)
With an undeclared checked exception for interface A:
interface A{ void x(); }
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.x(Unknown Source) at X.main(X.java:22) Caused by: java.io.IOException at X$1.invoke(X.java:19) ... 2 more
A dynamic proxy can throw checked exception if the exception is declared in the signature of the method of the interface it is proxying. From the Sun's Dynamic Proxy reference:
If an exception is thrown by the invoke method, it will be also thrown by the method invocation on the proxy instance.
The exception's type must be assignable to either any of the exception types declared in the signature of the interface method or to the unchecked exception types java.lang.RuntimeException or java.lang.Error.
If a checked exception is thrown by invoke that is not assignable to any of the exception types declared in the throws clause of the interface method, then an UndeclaredThrowableException will be thrown by the method invocation on the proxy instance. The UndeclaredThrowableException will be constructed with the exception that was thrown by the invoke method.
====================================================
Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
动态代理的定义:一个动态代理类在运行期implements一组interface,使得interface实现类的方法调用被分派至其他的类(另外的interface实现类或者任意的类)的方法。讲得更通俗一些,要了解动态代理,我们就要知道什么东西动态了,代理了什么?首先,一个Proxy代理了一组interface的方法。注意,代理的是interface,而不是Class,也不是abstract Class;其次,Proxy具有的型别由绑定的interface所决定的,动态就体现在此。
public interface Resource { public void operationA(); public void operationB(); } public class ConcreteResource implements Resource { public void operationA() { System.out.println("Operation A."); } public void operationB() { System.out.println("Operation B."); } } public class DynamicProxy implements InvocationHandler { private Resource resource; public DynamicProxy() { resource = new ConcreteResource(); } public Resource create() { Resource returnResource = null; returnResource = (Resource) Proxy.newProxyInstance(Resource.class.getClassLoader(), new Class[]{ Resource.class }, this); return returnResource; } public Object invoke(Object proxy, Method method, Object[] args) { Object o = null; try { if (method.getName().equals("operationA")) { System.out.println("OperationA in Proxy"); } else { o = method.invoke(resource, args); } } catch (Exception e) { e.printStackTrace(); } return o; } } public class Test { public static void main(String[] args) { DynamicProxy proxy = new DynamicProxy(); Resource resource = proxy.create(); resource.operationA(); } }
阅读上述代码:上述就是一个简单的动态代理的例子。我们可以看到Dynamic Proxy并没有实现Resource这个接口,但是包含了Resource接口实现类的实例;在Dynamic Proxy的create方法中,通过调用Proxy.newProxyInstance创建一个Proxy,并将该Proxy与Resource接口绑定,最后将Proxy显式类型转换成Resource接口类型并返回,这样调用者就可以通过Proxy调用interface定义的方法了;由于 Proxy与Resource接口绑定了,对Resource接口的方法调用,都会交由Proxy的invoke方法去处理。而invoke方法会根据不同的方法,或给以全新的实现,或直接将方法调用交给Proxy中包含的Resource接口实现类的实例去处理。综合上面所说的,作为一个Dynamic Proxy,它必须满足以下三个条件:
1、实现了InvocationHandler接口,实现接口中定义的invoke方法;
2、包含接口实现类的实例;
3、通过Proxy.newProxyInstance方法实现Proxy与接口之间的绑定。
发表评论
-
由安装JDK想到的
2013-07-31 19:03 902装了这么多年jdk,我发现网上很多安装jdk的文章对于某些问题 ... -
由一个js错误想到的.
2013-04-10 14:59 959背景知识:Java 6提供对执行脚本语言的支持,这个支持来自于 ... -
Java枚举的使用
2012-09-19 14:47 730public static enum DriverNa ... -
[转]关于Runtime.exec
2012-04-06 17:26 857import java.util.*; import ja ... -
Class的当前路径
2012-03-16 17:22 740在java中取得当前路径的方法很多, 有一种方法可以在随时在任 ... -
How to deal with “java.lang.OutOfMemoryError: PermGen space” ?
2012-03-08 15:42 806How to deal with “java.lang.Out ... -
如何给xml文件添加新的element
2011-12-06 16:42 1179下面是一个例子, 如何添加新的</property> ... -
Useful Java code samples
2011-11-25 12:42 722Java I/O Copy a File public v ... -
[转]一个保证store内容顺序不变的properties实现
2011-11-25 12:36 1897package com.jianrc.util; imp ... -
String比较方法结果
2011-11-18 12:18 891A= "abcd " B= " ... -
[转] 关于System.getProperty("os.arch")
2011-11-01 16:25 1387Java's "os.arch" Syst ... -
Java如何更新properties的多个值
2011-10-31 19:16 2257这个例子用使用了propertie的store方法, 他的优点 ... -
抽象类与接口杂谈
2011-09-23 11:14 8231.什么是抽象类? a. 抽象类是仅供派生的类, ...
相关推荐
java设计模式【之】Cglib动态代理【源码】【场景:帮爸爸买菜】 /** * 代理模式 * 在开发者的角度来看,创建一个代理对象,提供给用户使用,避免用户直接访问真正的对象 * 在用户角度来看,就是普通的类方法调用...
它通过访问gRPC服务公开的反射API读取protobuf服务定义,并将HTTP和JSON请求动态转换为gRPC调用。 创建gRPC Mate的目的是提供一种非常轻松地从gRPC服务器提供HTTP和JSON的方式,而无需共享protobuf定义文件,没有...
JAVA的反射机制与动态代理运行时类型信息(RunTime Type Information,RTTI)使得你在程序运行时发现和使用类型 信息。RTTI主要用来运行时获取向上转型之后的对象到底是什么具体的类型。
字节码生成库是生成和转换java字节码的高级api。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间...
使用动态WAN ip将代理反向转换为小工具或NAT后面的家庭http服务器。 需要两个“服务器”:一个在Internet中供您连接以进行传播,第二个在您家中用于服务代理请求。 它是如何工作的 启动后, client.js进行永久性...
快速的“这是怎么做的”事情来理解动态代理。 我想了解如何从手动编写包装器到通过接口和包装的实现动态创建包装器。 所以不要这样: public class FoodShop { Pastry getFood ( Pound money ) { Euro euro = ...
用于生成和启用一个代理类型的NavMesh表面的NavMeshSurface。 NavMeshModifier - 基于转换层次结构影响NavMesh区域类型的NavMesh生成。 NavMeshModifierVolume - 影响基于卷的NavMesh区域类型的NavMesh生成。 ...
(2)Android动态加载APK文件(代理模式) (3)Hook技术动态加载APK文件中的Activity 二、Android 动态加载dex文件 1.反射方式加载(较麻烦,不介绍),需要反射出具体的方法等 2.接口编程的方式加载(以下重点介绍...
Smiley的HTTP代理Servlet 这是Java Servlet形式的HTTP代理(也称为网关)。 HTTP代理对于AJAX应用程序与托管... 我发现这样的代理可以支持有限的HTTP子集(例如仅GET请求),或遭受其他实现问题,例如性能问题或URL转
通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。 二、CGLIB原理 CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。...
解决了两种情况下动态代理程序网络中的组共识问题:(i)通信拓扑正在切换,并且切换在任意拓扑之间任意发生; (ii)通信拓扑正在切换,并且该切换在有限拓扑之间任意地发生,并且存在通信延迟。 我们介绍了双树...
JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现. Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的...
Yoya-thumber Yoya-thumber是动态图像缩略图代理。特征支持图像缩放。 放大和缩小。 您可以指定输出宽度或高度。 易于使用。 由于它充当HTTP代理,因此您只需要将原始图片网址传递给yoya-thumber。 支持多种图像格式...
蓝色大气的工商记账,公司注册,企业资质业务办理公司网站响应式模板。主要有:关于我们、资质代理、工商代理、代理记账、资质转让、案例展示、新闻动态、联系我们等16个页面html下载。
使用代理枚举模拟动态调度和 ,它将所有方法调用推迟到其变体。 介绍 在 Rust 中,动态调度是使用 trait 对象( dyn Trait )完成的。 它们使我们能够拥有运行时多态性,这是一种表达类型实现特定特征而忽略其具体...
文档描述在我的文档资源里搜《将XML文件转换成对象,然后存到...涉及到的技术主要用:Dom4j技术,Cglib动态代理技术,java反射原理,不是最精简的,相信你看了之后自己也有一定的想法,想把它完成为自己的小工具。
该项目是通过引导的。 您将在下面找到一些有关如何执行常见任务的信息。 您可以在找到本指南的最新版本。 目录 自动格式化代码 更改页面<title> 安装依赖项 ... 在服务器上生成动态<met