您的位置:首页 > 编程语言 > Java开发

Java静态代理和动态代理

2014-03-18 10:48 369 查看
首先声明,本为并非原创,大量参考自http://layznet.iteye.com/blog/1182924,一方面做个备份,另一方面也是自己学习的过程。

一、代理
对一个类(委托类,实际完成工作的那个类)方法的调用交给另一个类(代理类,可以静态或动态生成)来完成。如果委托类和代理类实现了同一个接口,那么代理就可以很方便的完成。



二、静态代理
程序运行前代理类和委托类的关系就已经确定,代理类的字节码文件已经存在,代理不是运行时生成。

Code list 1, 接口定义:
package proxy.staticy;
public interface Subject {
void dealTask(String taskName);
}
Code list 2,委托类,真正做事情的类:
package proxy.staticy;
public class RealSubject implements Subject {
@Override
public void dealTask(String taskName) {
System.out.println("正在执行任务: " + taskName);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Code list 3,代理类:

package proxy.staticy;
public class ProxySubject implements Subject {
private Subject delegate;
public ProxySubject(Subject delegate) {
this.delegate = delegate;
}
@Override
public void dealTask(String taskName) {
long start = System.currentTimeMillis();
delegate.dealTask(taskName);
long end = System.currentTimeMillis();
System.out.println("任务耗时" + (end - start) + "毫秒");
}
}
Code list 4,生成代理的工厂类:

package proxy.staticy;
public class SubjectStaticFactory {
public static Subject getInstance() {
return new ProxySubject(new RealSubject());
}
}
Code list 5,模拟客户端:

package proxy.staticy;
public class Client1 {
public static void main(String[] args) {
Subject myProxy = SubjectStaticFactory.getInstance();
myProxy.dealTask("Task one");
}
}
三、动态代理

代理类的源码在运行时有虚拟机反射生成,因此不存在字节码文件,代理类和委托类的关系在运行时确定。
Code list 6,动态代理对应的调用处理器:(说白了就是类似于代理的类)
/**
* 动态代理对应的调用处理器
*/
package proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class SubjectInvocationHandler implements InvocationHandler {

// 代理类持有一个委托类的对象引用
private Object delegate;

public SubjectInvocationHandler(Object delegate){
this.delegate = delegate;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();

// Method的invoke返回Object对象方法执行的结果
method.invoke(delegate, args);

long end = System.currentTimeMillis();

System.out.println("任务执行耗时"+(end - start)+"毫秒");

return null;
}
}
Code list 7,生成动态代理对象的工厂类:

/**
* 生成动态代理对象的工厂.
*/
package proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import proxy.staticy.RealSubject;
import proxy.staticy.Subject;
/**
* 客户端调用此方法获得代理对象,
* 对客户端来说,并不知道获取的是代理对象还是委托对象。
*/
public class DynamicProxyFactory {
public static Subject getInstance() {
Subject delegate = new RealSubject();
InvocationHandler handler = new SubjectInvocationHandler(delegate);
Subject proxy = (Subject) Proxy.newProxyInstance(
delegate.getClass().getClassLoader(),
new Class[] {Subject.class},
handler);
return proxy;
}
}
Code list 8,模拟客户端:
package proxy.dynamic;
import proxy.staticy.Subject;
public class Client2 {
public static void main(String[] args) {
Subject myProxy = DynamicProxyFactory.getInstance();
myProxy.dealTask("Task two");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: