唐僧喜欢小龙女

导航

自定义一个异步回调的例子

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()+"我要执行别的任务了,异步任务执行完了会告诉主线程的");
    }
}

 

posted on 2021-10-04 20:46  与时具进&不忘初心  阅读(50)  评论(0编辑  收藏  举报