- 浏览: 899704 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
小宇宙_WZY:
膜拜一下大神,解决了我一个大问题,非常感谢 orz
【解惑】深入jar包:从jar包中读取资源文件 -
JKL852qaz:
感谢,遇到相同的问题!
【解惑】深入jar包:从jar包中读取资源文件 -
lgh1992314:
为什么java中调用final方法是用invokevirtua ...
【解惑】Java动态绑定机制的内幕 -
鲁曼1991:
说的都有道理,protected只能被同一级包的类所调用
【解惑】真正理解了protected的作用范围 -
鲁曼1991:
...
【总结】String in Java
代理(Proxy)实际上是一种设计模式。代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
//抽象角色: public interface Subject{ void request(); } //真实角色:实现了Subject的request()方法。 public class RealSubject implements Subject{ public void request() { System.out.println("我是真是角色"); } } //代理角色: public class ProxySubject implements Subject{ //以真实角色作为代理角色的属性 private RealSubject realSubject; public ProxySubject(RealSubject real){ this.realSubject=real; } //该方法改变了真是对象的request行为 public void request(){ System.out.println("之前设置新行为" ); realSubject.request(); //此处执行真实对象的request方法 System.out.println("之后设置新行为" ); } } //main测试 Subject sub=new ProxySubject(); Sub.request();
从上面的代码可以看出,我们可以通过建立代理角色ProxySubject来改变真实角色中的request方法功能(在原方法前后添加些功能)。这个应用非常的广泛,大家可以想想Struts2框架中拦截器在Action执行前所做的工作。但事实上Struts2框架是如何做到这一点的却是十分的复杂,我们需要往下看。
我们进一步想一下,当我们知道了抽象角色Subject的具体定义(request方法)的时候,我们当然可以很方便的通过包装Subject的真实角色RealSubject来定义一个能够部分改变真实角色行为的代理角色ProxySubject。但是很多情况下,我们事先并不知道需要代理的对象到底是什么类型的。或者说,只有在运行过程中才知道具体的对象。那么我们能否定义
一种具体行为的代理类,能够动态的实例化任何类型的代理对象呢?说白了,我们就是想做到下面这件事:
定义一种具体行为的代理类型:
public class ProxySubject implements interfaceX{
private ClassX obj;
public ProxySubject(ClassX obj){
this.obj=obj;
}
public void methodX(){
....新增行为
obj.methodx();//真实对象行为
....新增行为
}
}
运行时遇到不同类型的对象,都能够使用ProxySubject代理来完成新的行为:
ClassA oa=....
new ProxySubject(oa).methodX;
ClassA ob=....
new ProxySubject(oa).methodX;
做到这一点是很困难的,但并非不可能,Java的代理机制就能够帮助我们完成这件事。
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
(1) InvocationHandler接口,是代理实例的调用处理程序实现的接口。 它只有一个方法:invoke(Object proxy, Method method, Object[] args)。我们需要在实现InvocationHandler接口的具体类中的invoke方法内,编写代理行为的具体逻辑。然后将这个InvocationHandler对象传递给Proxy类中生成一个动态的代理对象。
(2) Proxy 类,提供用于创建动态代理类和实例的静态方法。其最重要的两个静态创建方法:
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
以上面的代码为例,编写一个动态代理类:
//完成代理行为 import java.lang.reflect.Method; import java.lang.reflect.InvocationHandler; public class DynamicSubject implements InvocationHandler { private Object sub; //被代理类 public DynamicSubject(Object obj) { sub = obj; } //无论何时调用代理类的方法,都会执行这个invoke方法的。 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用被代理对象的方法是:"+method.getName()+" "+method.getDeclaringClass()); System.out.println("之前设置新行为" ); method.invoke(sub,args); //动态调用被代理类的行为方法。 System.out.println("之后设置新行为" ); return null; } } //测试 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.io.*; static public void main(String[] args) throws Throwable{ Object real=new RealSubject(); //被代理对象 InvocationHandler handler = new DynamicSubject(real); //生成一个具体的代理行为 Object proxyed = Proxy.newProxyInstance(real.getClass().getClassLoader(), real.getClass().getInterfaces(),handler); //动态生成实现Subject接口的代理类 对象 if(proxyed instanceof Subject){ Subject subProx=(Subject)proxyed; subProx.request(); } else proxyed.toString(); } /* 调用被代理对象的方法是:request interface hr.login.Subject 之前设置新行为 我是真是角色 之后设置新行为 */
评论
发表评论
-
NIO
2010-08-05 10:36 0在JDK1.4以前,I/O输入输出处理,我们把它称为旧 ... -
【总结】Java线程同步机制深刻阐述
2010-05-16 10:21 6032全文转载:http://www.iteye ... -
【JDK优化】java.util.Arrays的排序研究
2010-05-12 21:06 9220作者题记:JDK中有很多算法具有优化的闪光点,值得好好研究。 ... -
【JDK优化】 Integer 自动打包机制的优化
2010-03-12 19:14 4226我们首先来看一段代码: Integer i=100; In ... -
【总结】Java与字符编码问题详谈
2009-12-30 09:11 9454一、字符集和字符编码方式 计算机只懂得0/1两种信号 ... -
【解惑】 正确理解线程等待和释放(wait/notify)
2009-12-29 13:40 19800对于初学者来说,下面这个例子是一个非常常见的错误。 /** ... -
【解惑】JVM如何理解Java泛型类
2009-12-16 11:08 12419//泛型代码 public class Pair<T& ... -
【解惑】正确的理解this 和 super
2009-12-05 09:46 4497转载: 《无聊 ... -
【解惑】真正理解了protected的作用范围
2009-11-21 18:00 5100一提到访问控 ... -
【总结】String in Java
2009-11-21 17:52 11002作者:每次上网冲杯Java时,都能看到关于String无休无止 ... -
【解惑】真正理解了protected的作用范围
2009-11-16 17:11 585一提到访问控制符protected,即使是初学者 ... -
总结Java标准类库中类型相互转化的方法
2009-11-09 21:57 210组一: ☆ String → byte[ ... -
方法没覆盖住带来的烦恼
2009-11-05 09:18 100Object类是所有类的祖宗,它的equals方法比较的 ... -
【解惑】数组向上转型的陷阱
2009-11-03 11:44 1897问题提出: 有两个类Manager和Em ... -
【总结】java命令解析以及编译器,虚拟机如何定位类
2009-11-01 16:25 5848学Java有些日子了,一直都使用IDE来写程序。这 ... -
【解惑】剖析float型的内存存储和精度丢失问题
2009-10-26 15:10 16138问题提出:12.0f-11.9f=0.10 ... -
【解惑】领略内部类的“内部”
2009-10-19 15:38 3609内部类有两种情况: (1) 在类中定义一个类(私有内部类 ... -
【解惑】深入jar包:从jar包中读取资源文件
2009-10-08 21:13 66031我们常常在代码中读取一些资源文件(比如图片,音乐,文 ... -
【解惑】理解java枚举类型
2009-09-26 09:37 3453枚举类型是JDK5.0的新特征。Sun引进了一个全新的关键字e ... -
编写自己的equals方法
2009-09-20 14:18 129在我的《令人头疼的"相等"关 ...
相关推荐
9. **反射**:Java反射允许在运行时检查类的信息并动态调用方法,是许多高级功能(如ORM框架、动态代理等)的基础。 10. **Lambda表达式和函数式编程**:Java 8引入了lambda表达式,简化了匿名内部类的使用,使得...
除此之外,书中的高级话题如反射、动态代理和Java虚拟机(JVM)的工作原理,也是许多Java开发者关注的重点。理解这些内容可以让你更好地优化代码,提高程序的运行效率,并为进行性能调优打下基础。 《JAVA解惑》...
《Java解惑(中文)》是一本专门为Java开发者编写的指南书籍,旨在解决在实际编程过程中遇到的各种疑惑和难题。本书以中文语言呈现,使得国内的Java程序员能够更轻松地理解并应用其中的知识。通过阅读这本书,读者...
《Java解惑(整理版本)》是一篇针对Java编程语言常见问题和疑惑的详细解析文章。博主通过深入探讨Java源码和使用工具的角度,帮助开发者解决实际开发中遇到的问题。以下将围绕标题和描述中的知识点进行展开: 1. *...
6. **反射与动态代理**:反射机制允许在运行时检查类、接口、字段和方法,而动态代理则能实现动态创建代理对象,这两者在Java中有着广泛的应用。 7. **泛型**:泛型提高了代码的类型安全性和重用性,书中可能详细...
7. **反射API**:Java反射机制允许我们在运行时检查类、接口、字段和方法的信息,甚至动态调用方法,这是许多高级功能如插件系统、序列化、动态代理的基础。 8. **泛型**:泛型是Java 5引入的新特性,用于提供类型...
Java面试题解惑系列主要涵盖了Java编程语言的核心概念、进阶技术以及在面试中常见的问题。这个压缩包可能包含了两本书籍,一本是"JAVA面试题解惑系列.pdf",另一本是"臧圩人--JAVA面试题解惑系列合集.pdf"。这些资源...
5. **反射与动态代理**:Java反射机制允许在运行时检查和修改程序行为,这可能导致一些不寻常的问题,而动态代理则涉及接口实现的动态生成,两者都是高级话题,可能包含在书中。 6. **集合框架**:Java集合框架包括...
Java面试解惑系列是针对Java开发者在求职过程中可能遇到的各种面试问题进行深入解析的一个专题。这一系列的内容旨在帮助程序员们更好地理解和掌握Java编程的核心概念、技术细节以及常见误区,从而在面试中展现出扎实...
"Java解惑"的主题旨在帮助开发者解决在学习和实践中遇到的复杂问题,加深对Java的理解。下面将详细探讨一些常见的Java知识点,以解答可能出现的疑惑。 1. **内存管理与垃圾回收**:Java通过自动垃圾回收机制管理...
《Java解惑》这本书无疑是为Java开发者量身打造的一本技术宝典,它涵盖了Java编程中的常见问题和难点,旨在帮助读者解决实际开发过程中遇到的困惑。书中可能涉及了类与对象、内存管理、多线程、异常处理、集合框架、...
《Java解惑》一书是为Java初学者和进阶者提供的一份宝贵参考资料,它旨在解答在Java编程过程中常见的困惑和难题。本书涵盖了Java语言的核心概念、语法特性以及实战应用,帮助读者深入理解Java编程的本质,提升编程...
"JAVA解惑.大全和问题解析"这个资源就是针对这些问题提供的一份详尽的解答指南。它涵盖了Java的基础知识、常见疑惑点以及易错知识点,旨在帮助Java初学者和进阶者解决实际编程中的困扰。 1. **基础概念解析**: - ...
在"JAVA面试题解惑系列"中,我们深入探讨了Java编程语言在面试中的关键知识点。这个系列旨在帮助Java开发者理解和解决那些在面试过程中可能遇到的棘手问题,揭示一些容易被忽视但至关重要的技术细节。以下是一些核心...
《JAVA解惑》这本书是Java编程领域的一本经典读物,以其深入浅出的方式解析了Java编程中的重点和难点。本书旨在帮助Java开发者解决实际编程过程中遇到的问题,提升编程技能和解决问题的能力。以下是对书中一些关键...
"JAVA面试题解惑系列"针对这一需求提供了全面的试题集,旨在帮助求职者深入理解Java语言的关键概念,提高面试成功率。这份资料可能包含了许多Java基础、进阶、设计模式、并发编程、JVM内存管理等方面的问题与解答。 ...
Java面试题解惑系列是为准备Java面试的开发者量身打造的一份宝贵资源,它涵盖了Java编程语言的基础、进阶以及实战应用等多个方面。在这个系列中,你可以找到一系列常见的面试问题,这些问题通常用来评估候选人的编程...