1、异步回调的理解
/**
*
* 一、什么是callBack?callBack 怎么理解
* 拆成 call和back 字面意思是稍后回呼,正式的意思是回调或者回呼
* 二、什么是异步
* A流程请求第三方接口B之后,不需要等待B应答,而是继续执行A剩余的逻辑,这样A的操作叫异步处理。
* 例如发消息也是一个异步
* 三、什么是异步回调
* 主调程序开启一个线程来进行异步操作,异步操作花的时间、成功还是失败都不影响主调程序的继续向下执行。
* 异步任务执行完成后,在新创建的线程里面调用主调程序传进来的另一个方法来返回结果,类比ajax(执行结果成功就调用成功的方法,失败就调用是失败的方法)
* 四、异步回调具体的举例说明
* 设想一个情景,A是处理业务的一个步骤,A需要解决一个问题,这时候A可以问B,让B来告诉A答案,
* 这期间,A可以继续做自己的事情,而不用因为B做的事而阻塞。于是,我们想到给B设置一个线程,让B去处理耗时的操作,
* 然后处理完之后在这个新线程里把结果显示出来。所以这个问题的要点就在于B处理完之后如何把结果告诉A。
* 我们可以直接在A中写一个方法对B处理完的结果进行处理,然后B处理完之后调用A这个方法。
* 这样A调用B去处理过程,B调用A的C方法去处理结果就叫做回调。
*
* A:当前程序的AsyncController 中的test方法。
* B:新的线程new Thread
* C:当前程序中的CallbackDemo 的onSuccess 和onFailure 方法。
*
*/
2、具体的例子
2.1 定义一个接口
public interface CallBackBody {
void onSuccess(Object context);
void onFailure(Object context);
public abstract void execute(Object context) throws Exception;
}
2.2 回调的工具类
public class CallBackTask {
private CallBackBody body;
public CallBackTask(CallBackBody body) {
this.body = body;
}
public void start(final Object context) {
final CallBackBody callBackBody = body;
final Thread t = new Thread(new Runnable() {
public void run() {
try {
callBackBody.execute(context);
} catch (Exception e) {
e.printStackTrace();
callBackBody.onFailure(context);
}
callBackBody.onSuccess(context);
}
});
t.start();
}
}
2.3 接口的实现类
@Component
public class CallbackDemo implements CallBackBody {
@Autowired
private RestTemplate restTemplate;
@Override
public void onSuccess(Object context) {
System.out.println("\n异步任务执行成功了");
System.out.println("\n异步任务执行完成!当前线程是"+Thread.currentThread().getName());
}
@Override
public void onFailure(Object context) {
System.out.println("异步任务执行失败了");
}
@Override
public void execute(Object context) throws Exception {
System.out.println("\n正在执行耗时操作...");
System.out.println(context);
restTemplate.postForObject("http://localhost:8004/test1",null,String.class);
System.out.println("\n异步任务执行完成!当前线程是"+Thread.currentThread().getName());
}
}
3、发起调用
@RestController
public class AsyncController {
@Autowired
CallbackDemo callbackDemo;
@RequestMapping("/test")
public void test(){
System.out.println("准备开始执行异步任务...");
final Object context = "上下文信息";
//开始异步调用
new CallBackTask(callbackDemo).start(context);
System.out.println("\n异步任务让别的线程执行了,当前线程是"+Thread.currentThread().getName()+"我要执行别的任务了,异步任务执行完了会告诉主线程的");
}
}