如何使用Proxy模式及Java内建的动态代理机制
来源:互联网 发布:网络教育概念股 编辑:程序博客网 时间:2024/05/17 00:59
原始出处:http://zhangjunhd.blog.51cto.com/113473/69996
1.Proxy模式
代理模式支持将某些操作从实际的对象中分离出来,通过它的代理类提供处理。这样便于修改和管理这些特定的操作。
下面示例一个代理模式的实现。
<!--[if !vml]-->
<!--[endif]-->
<<interface>>Subject.java
package com.zj.proxy;
publicinterface Subject {
void operation1();
void operation2(String arg);
}
现实类RealSubject.java
package com.zj.proxy;
publicclass RealSubjectimplements Subject {
publicvoid operation1() {
System.out.println("Realer do operation1");
}
publicvoid operation2(String arg) {
System.out.println("Realer do operation2 with " + arg);
}
}
代理类ProxySubject.java
package com.zj.proxy;
publicclass ProxySubjectimplements Subject {
private Subjectproxied;//被代理对象
public ProxySubject(Subject proxied) {
this.proxied = proxied;
}
publicvoid operation1() {
System.out.println("Proxyer do operation1");
proxied.operation1();
}
publicvoid operation2(String arg) {
System.out.println("Proxyer do operation2 with " + arg);
proxied.operation2(arg);
}
}
测试类SimpleProxyDemo.java
package com.zj.proxy.client;
import com.zj.proxy.Subject;
import com.zj.proxy.RealSubject;
import com.zj.proxy.ProxySubject;
publicclass SimpleProxyDemo {
publicstaticvoid consumer(Subject subject) {
subject.operation1();
subject.operation2("ZJ");
}
publicstaticvoid main(String[] args) {
RealSubject real = new RealSubject();
System.out.println("===Without Proxy===");
consumer(real);
System.out.println("===Use Proxy===");
consumer(new ProxySubject(real));
}
}
结果:
===Without Proxy===
Realer do operation1
Realer do operation2 with ZJ
===Use Proxy===
Proxyer do operation1
Realer do operation1
Proxyer do operation2 with ZJ
Realer do operation2 with ZJ
2.使用Java的动态代理机制
设计一个类用于实现InvocationHandle接口,InvocationHandler 是代理实例的调用处理程序实现的接口。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
<<interface>>InvocationHandle.java
package java.lang.reflect;
publicinterface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
对应invoke参数:
[1]proxy - 在其上调用方法的代理实例;
[2]method - 对应于在代理实例上调用的接口方法的 Method 实例;
[3]args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。
现在设计一个类实现该接口,并提供代理实例。
DynamicProxyHandler.java
package com.zj.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
publicclass DynamicProxyHandlerimplements InvocationHandler {
private Objectproxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("**** proxy: ****\n" + proxy.getClass()
+ "\nmethod: " + method + "\nargs: " + args);
if (args !=null)
for (Object arg : args)
System.out.println(" " + arg);
return method.invoke(proxied, args);
}
}
这里的private Objectproxied;即代理实例,也即上文代理模式中介绍的RealSubject对象。
在invoke()方法中,我们会打印它的所有参数,并调用当前代理的方法。
测试类DynamicProxyDemo.java
package com.zj.proxy.client;
import java.lang.reflect.Proxy;
import com.zj.proxy.Subject;
import com.zj.proxy.RealSubject;
import com.zj.proxy.dynamic.DynamicProxyHandler;
publicclass DynamicProxyDemo {
publicstaticvoid consumer(Subject subject) {
subject.operation1();
subject.operation2("ZJ");
}
publicstaticvoid main(String[] args) {
RealSubject real = new RealSubject();
System.out.println("===Without Proxy===");
consumer(real);
System.out.println("===Use Proxy===");
Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class
.getClassLoader(),new Class[] { Subject.class },
new DynamicProxyHandler(real));
consumer(proxy);
}
}
这里通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)生成代理类,并传递与其关联的调用处理程序new DynamicProxyHandler(real)。
对于newProxyInstance()的参数:
[1]loader - 定义代理类的类加载器 ;
[2]interfaces - 代理类要实现的接口列表 ;
[3]h - 指派方法调用的调用处理程序 。
测试结果:
===Without Proxy===
Realer do operation1
Realer do operation2 with ZJ
===Use Proxy===
**** proxy: ****
class $Proxy0
method: public abstract void com.zj.proxy.Subject.operation1()
args: null
Realer do operation1
**** proxy: ****
class $Proxy0
method: public abstract void com.zj.proxy.Subject.operation2(java.lang.String)
args: [Ljava.lang.Object;@de6f34
ZJ
Realer do operation2 with ZJ
从结果可以发现,通过代理可以得到当前被调用的方法,及其参数。代理过程可以基于此进行逻辑处理,测试程序只是简单的打印这些相关信息。
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/69996
- 如何使用Proxy模式及Java内建的动态代理机制
- 如何使用Proxy模式及Java内建的动态代理机制
- 如何使用Proxy模式及Java内建的动态代理机制
- 如何使用Proxy模式及Java内建的动态代理机制
- 如何使用Proxy模式及Java内建的动态代理机制
- Proxy模式及Java内建的动态代理机制
- java动态代理模式Proxy之JDK动态代理机制
- 代理及动态代理模式(Proxy、DynamicProxy)
- 使用Java的Proxy类实现动态代理(Dynamic Proxy)
- Java设计模式-----Proxy模式(动态代理)
- Java设计模式-----Proxy模式(动态代理)
- java设计模式:动态代理模式 Proxy
- java动态代理Proxy 内部机制
- Java的动态代理Proxy
- Java动态代理一------动态类Proxy的使用
- Java动态代理--动态类Proxy的使用
- Dynamic Proxy 动态代理模式的Java实现
- (Dynamic Proxy)动态代理模式的Java实现
- jdk1.7的新特性
- JVM
- linux 内核驱动编程 简单例子 与_IO, _IOR, _IOW, _IOWR 宏解析
- java web开发 购物车功能实现
- android java获取当前时间的总结
- 如何使用Proxy模式及Java内建的动态代理机制
- Hadoop LZO 安装教程
- JVM优化
- 在Linux下使用goagent遇到的问题和解决办法
- Android UncaughtExceptionHandler捕获崩溃异常
- php正则匹配汉字!
- PDF屏蔽打印,隐藏工具栏和菜单栏
- 崩溃
- Secure Network (ssh端口映射)-----图详细可以使用