回调机制是指调用者需要使用提供者的功能完成任务,然后提供者再使用调用者提供的回调方法通知调用者功能完成的情况;
在Java中方法的调用方式有同步调用、异步调用,回调方式也有同步回调和异步回调;
回调机制通常使用接口(面向接口编程,扩展性更好)进行回调方法的声明,回调接口的实现类进行回调功能的重写,在方法中需要将回调接口的实现类对象作为方法参数传递给提供者的方法,然后在提供者中进行方法回调;
一 同步回调
1.1 使用接口
定义回调接口和实现类重写回调方法:
public interface ZeroCallback {
String successCallback();
String failCallback();
}
public class MangoCallback implements ZeroCallback {
// 需要将服务提供者作为参数传递过来
private WorkService workService;
public MangoCallback(WorkService workService) {
this.workService = workService;
}
public void execute() {
System.out.println(threadName() + "\t调用者, 开始执行业务功能...");
workService.service(this);
System.out.println(threadName() + "\t调用者, 结束执行业务功能...");
}
@Override
public String successCallback() {
System.out.println("业务完成成功, 调用成功回调方法");
return "success";
}
@Override
public String failCallback() {
System.out.println("业务完成失败, 调用失败回调方法");
return "fail";
}
public String threadName() {
return Thread.currentThread().getName();
}
}
定义提供者的功能:
/**
* 服务提供者
*/
public class WorkService {
/**
* 服务提供者的方法参数中, 必须要有调用者类型作为方法参数, 用来执行回调
*
* @param zeroCallback
*/
public void service(ZeroCallback zeroCallback) {
System.out.println(threadName() + "\t提供者, 开始执行功能服务代码...");
zeroCallback.successCallback();
System.out.println(threadName() + "\t提供者, 结束执行功能服务代码...");
}
public String threadName() {
return Thread.currentThread().getName();
}
}
功能测试:
public class MangoTest {
public static void main(String[] args) {
testCallback();
}
public static void testCallback() {
WorkService workService = new WorkService();
MangoCallback mangoCallback = new MangoCallback(workService);
mangoCallback.execute();
}
}
方法执行结果:
main 调用者, 开始执行业务功能...
main 提供者, 开始执行功能服务代码...
业务完成成功, 调用成功回调方法
main 提供者, 结束执行功能服务代码...
main 调用者, 结束执行业务功能...
执行调用者的MangoCallback的execute方法,会调用提供者WorkService的service方法,而且会将调用者对象作为方法参数传递到service方法,在WorkService的service方法会执行回调方法;
调用者和提供者都是在同一个线程里面执行,无论提供者耗时多长时间返回service方法,调用者都是阻塞等待;
1.2 使用抽象类
public interface ZeroCallback {
String successCallback();
String failCallback();
}
/**
* 定义抽象类, 实现接口会继承接口中的回调方法, 然年定义一个业务execute方法
*/
public abstract class AbstractCallback implements ZeroCallback {
// 需要将服务提供者作为参数传递过来
public WorkService workService;
public AbstractCallback(WorkService workService) {
this.workService = workService;
}
public abstract void execute();
public String threadName() {
return Thread.currentThread().getName();
}
}
1.2.1 使用抽象类的子类对象
public class MangoAbstractCallback extends AbstractCallback {
public MangoAbstractCallback(WorkService workService) {
super(workService);
}
@Override
public void execute() {
System.out.println(threadName() + "\t调用者, 开始执行业务功能...");
workService.service(this);
System.out.println(threadName() + "\t调用者, 结束执行业务功能...");
}
@Override
public String successCallback() {
System.out.println("业务完成成功, 调用成功回调方法");
return "success";
}
@Override
public String failCallback() {
System.out.println("业务完成失败, 调用失败回调方法");
return "fail";
}
}
方法测试:
public class MangoTest {
public static void main(String[] args) {
// testCallback();
testCallback2();
}
public static void testCallback() {
WorkService workService = new WorkService();
MangoCallback mangoCallback = new MangoCallback(workService);
mangoCallback.execute();
}
public static void testCallback2() {
WorkService workService = new WorkService();
MangoAbstractCallback callback = new MangoAbstractCallback(workService);
callback.execute();
}
}
1.2.2 使用抽象类的匿名内部类
public class MangoTest {
public static void main(String[] args) {
// testCallback();
// testCallback2();
testCallback3();
}
public static void testCallback() {
WorkService workService = new WorkService();
MangoCallback mangoCallback = new MangoCallback(workService);
mangoCallback.execute();
}
public static void testCallback2() {
WorkService workService = new WorkService();
MangoAbstractCallback callback = new MangoAbstractCallback(workService);
callback.execute();
}
public static void testCallback3() {
WorkService workService = new WorkService();
AbstractCallback callback = new AbstractCallback(workService) {
@Override
public void execute() {
System.out.println(threadName() + "\t调用者, 开始执行业务功能...");
workService.service(this);
System.out.println(threadName() + "\t调用者, 结束执行业务功能...");
}
@Override
public String successCallback() {
System.out.println("业务完成成功, 调用成功回调方法");
return "success";
}
@Override
public String failCallback() {
System.out.println("业务完成失败, 调用失败回调方法");
return "fail";
}
};
callback.execute();
}
}
二 异步回调
public interface ZeroCallback {
String successCallback();
String failCallback();
}
public class AsyncMangoCallback implements ZeroCallback {
// 需要将服务提供者作为参数传递过来
private WorkService workService;
public AsyncMangoCallback(WorkService workService) {
this.workService = workService;
}
public void execute() {
System.out.println(threadName() + "\t调用者, 开始执行业务功能...");
// 异步执行
new Thread(() -> workService.service(this)).start();
System.out.println(threadName() + "\t调用者, 结束执行业务功能...");
}
@Override
public String successCallback() {
System.out.println("业务完成成功, 调用成功回调方法");
return "success";
}
@Override
public String failCallback() {
System.out.println("业务完成失败, 调用失败回调方法");
return "fail";
}
public String threadName() {
return Thread.currentThread().getName();
}
}
功能测试:
public class MangoTest {
public static void main(String[] args) {
// testCallback();
// testCallback2();
// testCallback3();
testCallback4();
}
public static void testCallback4() {
WorkService workService = new WorkService();
AsyncMangoCallback mangoCallback = new AsyncMangoCallback(workService);
mangoCallback.execute();
}
}
方法执行结果:
main 调用者, 开始执行业务功能...
main 调用者, 结束执行业务功能...
Thread-0 提供者, 开始执行功能服务代码...
业务完成成功, 调用成功回调方法
Thread-0 提供者, 结束执行功能服务代码...
执行调用者的MangoCallback的execute方法,会调用提供者WorkService的service方法,而且会将调用者对象作为方法参数传递到service方法,在WorkService的service方法会执行回调方法;
在main线程内执行调用者的MangoCallback的execute方法,在Thread-0线程内调用提供者WorkService的service方法,调用者不会阻塞等待;