彻底把回调的各种的使用都弄明白了,呵呵,记录一下。当然下面的回调是最粗浅的使用方式,昨天看了老外写的callback,那真是鬼斧神工呀,哎,国内的程序员和国外的程序员始终不是一个档次的,还是努力学习吧。
客户端有一段本地代码,这段代码需要在客户端请求服务端执行完某个操作后由服务端调用,这段本地代码就是回调函数。
为什么叫回调?
client先请求server执行服务端的某个方法S,在服务端执行S()完毕之后,由server端反过来调用client端的方法C().
简单举个例子,例如Ext.Ajax.request的异步请求,client向服务端执行请求request,服务端根据请求执行某个操作S,S执行完毕之后回调client的两个方法:success()和fail(),success和fail都是回调方法。当server执行S完毕之后,通知client执行。
借了老外的图用一下:
实现过程:
(1)将客户端需要被回调的代码callBackMethod()封转成CallbackIntf。
(2)服务端要回调客户端的代码,则必须持有客户端对象的引用,即客户端需要向服务端注册。
(3)各种不同类型的client分别实现CallbackIntf,则每个客户端都有callBackMethod()。同时,服务端需要提供执行callBackMethod()的入口.
实现方式上,可以通过向服务端注册回调接口(通过组合方式实现)以及匿名内部类的方式实现。
1、通过注册方式实现(向服务端注册 实现回调接口的类)
package com.zhaoyp.callback.demo03; //回调接口 public interface CallbackIntf { public void callBackMethod(); }
package com.zhaoyp.callback.demo03; //客户端 public class Client implements CallbackIntf { //普通函数 public void directMethod() { System.out.println("client request for server.."); } //回调函数 @Override public void callBackMethod() { System.out.println("client callback code execute.."); } }
package com.zhaoyp.callback.demo03; public class Server { //服务端持有客户端引用 private Client object; //向服务端注册客户端 //这里是一个典型的setClient()方法 public void register(Client obj) { this.object = obj; } //服务端执行回调 public void executeCallBack() { object.callBackMethod(); } //服务端的方法 public void service() { System.out.println("server service().."); } }
package com.zhaoyp.callback.demo03; public class CallbackTest { public static void main(String[] args) { Client client = new Client(); Server server = new Server(); //客户端向服务端注册,让服务端知道客户端的回调函数 server.register(client); //客户端发送请求给服务端 client.directMethod(); //服务端处理请求 server.service(); //请求完毕之后,由服务端执行回调函数 server.executeCallBack(); } }
2、通过匿名内部类方式实现
这种方式是根据具体的使用去生成匿名的客户端,即客户端成了一个匿名内部类。实质不变,可是形式变化很大。
回调接口不变
package com.zhaoyp.callback.demo06; //回调接口 public interface CallbackIntf { public void callbackMethod(); }
普通方法执行完毕后,由 服务端执行回调函数
package com.zhaoyp.callback.demo06; public class Server { //执行回调 public void executeCallback(CallbackIntf client) { client.callbackMethod(); } //普通方法 public void service() { System.out.println("do service().."); } }
package com.zhaoyp.callback.demo06; //测试类 public class CallbackTest { public static void main(String[] args) { Server server = new Server(); server.service(); //通过匿名内部类执行回调操作,匿名内部类相当于前面的client server.executeCallback(new CallbackIntf() { @Override public void callbackMethod() { System.out.println("inner class callback.."); } }); } }
回调模式在Ajax请求,RMI中应用的非常广泛,昨天在国外论坛上看到一个老外写的一篇帖子,非常之佩服。