自定义一个异步回调的例子
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()+"我要执行别的任务了,异步任务执行完了会告诉主线程的"); } }