回调函数
参考了许多资料,感觉具体说的都不清楚,本文记录自己的理解。
- 回调,callback ,在java中指可以被 被调用方调用的函数(前提是被调用方有该函数的引用)。根据回调时机的不同,回调函数可分为 同步回调和异步回调
- 同步回调:指函数调用过程是阻塞的,主函数必须等回调函数执行完毕才能执行下一步操作。
- 异步回调:主函数无须等待回调函数的执行完成与否即可执行下一步操作。一般此时回调函数通过开启新线程执行具体的代码。
一般被调用方的某个方法被调用时,需要调用方提供对应的回调方法,回调的关键点就在于回调接口Inteface的实现。
为了加深理解,以发送短信为例进行说明异步调用的实现。
现有客户cleint,运营商MsgCompany,运营商有短信发送服务器MsgServer
其中MsgServer提供msgSend的方法,该方法在被调用5秒后完成。
client客户指定发送短信运营商并调用短信运营商的发送短信方法。
在短信发送完成后需要运营商通知client短信发送完成,具体的通知方式由client决定。
上代码
通知接口
package com.taku.send;
// 提醒服务接口,可用于客户自定义提醒方式
public interface Notice {
// 如何提醒
public void notice();
}
客户client
package com.taku.send;
// 客户,想要发送短信
public class Client {
// 具体的运营商
MsgCompany msgCompany;
// 具体的提醒方式
Notice notice;
public Client(Notice notice, MsgCompany msgCompany) {
this.notice = notice;
this.msgCompany = msgCompany;
}
public MsgCompany getMsgCompany() {
return msgCompany;
}
public void setMsgCompany(MsgCompany msgCompany) {
this.msgCompany = msgCompany;
}
// 发送短信
public void sendMsg(String msg) {
// 调用运营商的发短信并传递提醒方式--即回调
msgCompany.sendMsg(msg,notice);
}
}
package com.taku.send;
// 运营商,可以调用短信发送服务器的短信发送方法
public class MsgCompany {
public void sendMsg(String msg,Notice notice){
MsgServer.sendMsg(msg,notice);
}
}
package com.taku.send;
// 模拟短信发送服务器,5秒后回调通知方法
public class MsgServer {
public static void sendMsg(String msg, Notice notice) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("服务器短信已发送给客户,短信内容是:" +msg);
notice.notice();
}
}).start();
}
}
测试调用
package com.taku.send;
import java.util.logging.Logger;
public class SendTest {
public static void main(String[] args) {
Logger logger = java.util.logging.Logger.getLogger("SendTest");
// 创建一个运营商
MsgCompany msgCompany = new MsgCompany();
// 创建一个客户A,A客户的提醒方式是打电话到123
Client A = new Client(new Notice() {
@Override
public void notice() {
System.out.println("打电话到123");
}
}, msgCompany);
Client B = new Client(new Notice() {
@Override
public void notice() {
System.out.println("发个邮件到我的邮箱@qq.com");
}
}, msgCompany);
A.sendMsg("这是A发送的短信");
B.sendMsg("这是B发送的短信");
logger.info("短信发送调用完成");
}
}
执行结果
另外可以通过让Client实现Notice接口从而实现对不同类别客户群体的通知方式。改造如下
package com.taku.send;
// 客户实现notice接口,实现同意客户类群的通知方式
public class ClientNew implements Notice{
public ClientNew(MsgCompany msgCompany) {
this.msgCompany = msgCompany;
}
public MsgCompany getMsgCompany() {
return msgCompany;
}
public void setMsgCompany(MsgCompany msgCompany) {
this.msgCompany = msgCompany;
}
MsgCompany msgCompany;
public void sendMsg(String msg) {
// 这是传this
msgCompany.sendMsg(msg,this);
}
// 重写notice()
@Override
public void notice() {
System.out.println("所有的新客户都是使用的一样的通知方式,那就是QQ提醒");
}
}
调用与结果