java复习之动态代理
来源:互联网 发布:淘宝服务器时间 编辑:程序博客网 时间:2024/06/15 16:56
在某些情况下,我们不希望或是不能直接访问对象 A,而是通过访问一个中介对象 B,由 B 去访问 A 达成目的,这种方式我们就称为代理。这里对象 A 所属类我们称为委托类,也称为被代理类,对象 B 所属类称为代理类。代理优点有:
隐藏委托类的实现
解耦,不改变委托类代码情况下做一些额外处理,比如添加初始判断及其他公共操作
根据程序运行前代理类是否已经存在,可以将代理分为静态代理和动态代理。
由开发人员编写或是编译器生成代理类的方式都属于静态代理;
代理类在程序运行前不存在、运行时由程序动态生成的代理方式称为动态代理。
实现动态代理包括三步:
(1). 新建委托类;(2). 实现InvocationHandler接口,这是负责连接代理类和委托类的中间类必须实现的接口;(3). 通过Proxy类新建代理类对象。
2.1 新建委托类
public interface Operate {
public void operateMethod1();public void operateMethod2();public void operateMethod3();
}
public class OperateImpl implements Operate {
@Overridepublic void operateMethod1() { System.out.println("Invoke operateMethod1"); sleep(110);}@Overridepublic void operateMethod2() { System.out.println("Invoke operateMethod2"); sleep(120);}@Overridepublic void operateMethod3() { System.out.println("Invoke operateMethod3"); sleep(130);}private static void sleep(long millSeconds) { try { Thread.sleep(millSeconds); } catch (InterruptedException e) { e.printStackTrace(); }}
}
Operate是一个接口,定了了一些函数,我们要统计这些函数的执行时间。
OperateImpl是委托类,实现Operate接口。每个函数简单输出字符串,并等待一段时间。
动态代理要求委托类必须实现了某个接口,比如这里委托类OperateImpl实现了Operate,原因会后续在微博公布。
2.2. 实现 InvocationHandler 接口
public class TimingInvocationHandler implements InvocationHandler {
private Object target;public TimingInvocationHandler() {}public TimingInvocationHandler(Object target) { this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long start = System.currentTimeMillis(); Object obj = method.invoke(target, args); System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start)); return obj;}
}
target属性表示委托类对象。
InvocationHandler是负责连接代理类和委托类的中间类必须实现的接口。其中只有一个
public Object invoke(Object proxy, Method method, Object[] args)
函数需要去实现,参数:
proxy表示下面2.3 通过 Proxy.newProxyInstance() 生成的代理类对象。
method表示代理对象被调用的函数。
args表示代理对象被调用的函数的参数。
调用代理对象的每个函数实际最终都是调用了InvocationHandler的invoke函数。这里我们在invoke实现中添加了开始结束计时,其中还调用了委托类对象target的相应函数,这样便完成了统计执行时间的需求。
invoke函数中我们也可以通过对method做一些判断,从而对某些函数特殊处理。
2.3. 通过 Proxy 类静态函数生成代理对象
public class Main {
public static void main(String[] args) {
// create proxy instance
TimingInvocationHandler timingInvocationHandler = new TimingInvocationHandler(new OperateImpl());
Operate operate = (Operate)(Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[] {Operate.class},
timingInvocationHandler));
// call method of proxy instance operate.operateMethod1(); System.out.println(); operate.operateMethod2(); System.out.println(); operate.operateMethod3();}
}
这里我们先将委托类对象new OperateImpl()作为TimingInvocationHandler构造函数入参创建timingInvocationHandler对象;
然后通过Proxy.newProxyInstance(…)函数新建了一个代理对象,实际代理类就是在这时候动态生成的。我们调用该代理对象的函数就会调用到timingInvocationHandler的invoke函数(是不是有点类似静态代理),而invoke函数实现中调用委托类对象new OperateImpl()相应的 method(是不是有点类似静态代理)。
public static Object newProxyInstance(ClassLoader loader, Class
- java复习之动态代理
- Java 代理之 动态代理
- java之动态代理
- java之动态代理
- Java之动态代理
- java之动态代理
- java之动态代理
- java之动态代理
- Java之动态代理
- Java之动态代理
- java之动态代理
- java之动态代理
- java之动态代理
- Java动态代理之JDK动态代理
- CGlib动态代理复习
- Java复习之静态代理设计模式
- 【JAVA】代理模式之Java动态代理
- Java代理之JDK动态代理
- iOS 检测网络情况
- 读取短信自动填写验证码功能
- MyBatis-处理字段名与实体类名不一致的情况 -04
- 第五章,(while循环)1000以内的奇数和(C++)
- HDU {A} + {B}
- java复习之动态代理
- springMVC+mybatis+spring security<三>:使用数据库管理资源
- C语言编程需要注意的64位和32机器的区别
- Java BufferedReader下载网络文件
- jQuery ajax - ajax() 方法
- 心情记录-2015年5月26日 13:34:26
- LINUX DDR驱动知识
- 从导航栏下开始计算坐标
- CImage的学习