- 浏览: 161070 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
追求幸福:
每增加一个新的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 942装了这么多年jdk,我发现网上很多安装jdk的文章对于某些问题 ... -
由一个js错误想到的.
2013-04-10 14:59 994背景知识:Java 6提供对执行脚本语言的支持,这个支持来自于 ... -
Java枚举的使用
2012-09-19 14:47 769public static enum DriverNa ... -
[转]关于Runtime.exec
2012-04-06 17:26 907import java.util.*; import ja ... -
Class的当前路径
2012-03-16 17:22 787在java中取得当前路径的方法很多, 有一种方法可以在随时在任 ... -
How to deal with “java.lang.OutOfMemoryError: PermGen space” ?
2012-03-08 15:42 843How to deal with “java.lang.Out ... -
如何给xml文件添加新的element
2011-12-06 16:42 1240下面是一个例子, 如何添加新的</property> ... -
Useful Java code samples
2011-11-25 12:42 764Java I/O Copy a File public v ... -
[转]一个保证store内容顺序不变的properties实现
2011-11-25 12:36 1947package com.jianrc.util; imp ... -
String比较方法结果
2011-11-18 12:18 940A= "abcd " B= " ... -
[转] 关于System.getProperty("os.arch")
2011-11-01 16:25 1484Java's "os.arch" Syst ... -
Java如何更新properties的多个值
2011-10-31 19:16 2299这个例子用使用了propertie的store方法, 他的优点 ... -
抽象类与接口杂谈
2011-09-23 11:14 8641.什么是抽象类? a. 抽象类是仅供派生的类, ...
相关推荐
Java动态代理是面向切面编程(AOP)的一种实现方式,它允许我们在不修改原有代码的情况下,为已有的对象添加额外的功能。在Web开发中,动态代理常常用于增强业务逻辑,比如日志记录、权限检查等,使得代码更加模块化...
代理模式分为静态代理和动态代理两种主要形式,每种都有其特定的应用场景和优势。下面我们将深入探讨这两种代理模式,并通过一个“黄牛买票”的例子来具体说明。 首先,我们来看静态代理。静态代理是程序员在编译时...
Java反射(Reflection)和动态代理(Dynamic Proxy)是Java编程中的高级特性,它们为程序提供了强大的功能和灵活性。本文将深入探讨这两个主题,并通过源码分析来加深理解。 首先,让我们了解一下Java反射。反射机制...
Java的代理模式通过代理类提供了对委托类的扩展和控制,静态代理适合对已有代码不做修改的情况,而动态代理则提供了更高的灵活性和扩展性。在实际应用中,应根据项目需求和性能考虑选择静态代理或动态代理。对于需要...
本主题将深入探讨JVM技术,特别是反射与动态代理这两个关键特性。 一、JVM技术 1. 类加载机制:JVM通过类加载器(ClassLoader)来加载.class文件,分为启动类加载器、扩展类加载器和应用程序类加载器。类的加载...
Java中的动态代理、反射和拦截器是面向对象编程中非常重要的技术,它们在实现灵活性、扩展性和代码解耦方面发挥着关键作用。本资源提供的示例涵盖了这些核心概念,通过JDK动态代理、CGLIB动态代理以及拦截器链的实践...
Java JDK 动态代理是一种强大的特性,它允许我们在运行时创建代理对象,这些代理对象可以扩展或增强已存在的接口实现。动态代理在处理AOP(面向切面编程)场景、事件监听、性能监控等方面有着广泛的应用。下面我们将...
在编程领域,动态代理和工厂方法是两种非常重要的设计模式,它们在软件开发中起着至关重要的作用。这里我们将深入探讨这两种模式,并结合提供的文件名,即“005_Factory_Series_DesignPattern”和“006_Dynamic_...
动态代理和RMI(Remote Method Invocation)是Java中两种重要的分布式计算技术,它们在实际的软件开发中扮演着至关重要的角色。本篇将详细介绍这两个概念,以及如何通过源码和PPT来理解它们。 首先,让我们来理解...
动态代理和AOP是Java和Spring框架中的重要概念,它们为开发者提供了强大的代码复用和模块化设计的能力。本文将深入解析这两个主题,并结合提供的源码进行详细讲解。 首先,让我们了解一下动态代理。在Java中,动态...
JDK动态代理基于Java的接口机制实现,因此,要使用JDK动态代理,被代理的目标类必须实现至少一个接口。`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口是JDK动态代理的核心。Proxy类用于...
动态代理在Java编程中是一种非常重要的技术,它允许我们在运行时创建对象的代理,从而可以在不修改原有代码的情况下,为对象添加额外的功能。本压缩包包含关于三种主要的动态代理实现方式:JDK动态代理、CGLIB以及...
在Java中,基于动态代理和反射机制实现ORM可以提高代码的可维护性和灵活性。本篇文章将深入探讨如何在Java环境下,结合MySQL数据库,利用动态代理和反射技术来实现简单的ORM框架。 首先,我们需要了解动态代理和...
本文将深入探讨JAVA的反射机制,特别是其在动态代理中的应用。 #### 反射机制基础 反射机制的核心在于`java.lang.Class`类,它提供了运行时类型信息(RTTI),使得开发者可以在程序运行期间访问和操作类的信息。`...
Java动态代理是一种编程技术,主要用于在运行时创建一个新的对象,该对象可以作为现有接口的实现。动态代理的主要目的是为了在不修改原有代码的基础上,为已有的接口或类添加额外的功能,比如日志、事务管理、性能...
### JAVA类加载机制与动态代理 #### 一、类加载机制 ##### 1.1 类加载的时机 类加载机制负责将描述类的数据从`.class`文件加载到内存,并进行必要的校验、转换解析和初始化,使之成为可以被Java虚拟机直接使用的...
动态代理和静态代理是代理模式的两种主要实现方式,它们在Java编程中尤为常见。 首先,让我们从静态代理开始。静态代理是手动创建的代理类,它通常与被代理类位于同一个包下,并且实现相同的接口。在这个过程中,...
CGLib,全称为Code Generation Library,是一个强大的高性能的代码生成库,它在Java世界中被广泛应用,尤其是在动态代理、AOP(面向切面编程)等领域。这个“cglib实现动态代理依赖jar包”包含了两个核心的JAR文件:...
动态代理是实现AOP的一种常见技术,它允许我们在运行时创建对象的代理,从而在不修改原有代码的情况下添加额外的功能。本篇文章将深入探讨如何使用动态代理实现AOP。 1. **AOP概念** - AOP(Aspect Oriented ...
本话题主要围绕"Java分页"、"动态代理"以及"AOP(面向切面编程)"在Spring框架中的实现进行详细讲解。 首先,我们来看"Java分页"。在处理大量数据时,一次性加载所有数据不仅会消耗大量的内存,也可能导致用户界面...