java回调那点事, 回调最通俗的解释

前言

在程序中,通常想要获取信息需要去主动调用,比如调用get方法获取值。
但是这样有些场景就满足不了,比如你想要获取的信息产生的时间不确定。当然,你可以做个循环一直去get,直到get到想要的信息为止。但这并不是一个好办法。


回调,就是被动通知。我调个接口,并没有立刻获取到结果,没关系,等结果出来之后被调用者自动给我返回。这样的好处是我不需要重复去查询结果,解耦代码。

.

实现机制

现在通过买票的例子进行分析

场景:我买票,售票员通知我出票结果

分析:关键词是被通知,很显然,我的出票结果是被售票员通知的,但是怎么通知?很多网文一笔带过,难道真实情况真的是这么简单不值一提吗?

真相:实际上管理员是不能直接通知到我,而是有个中间人,对,我有个朋友叫小明,是他帮我转告售票员的"口述的"。所以真实的情况是:我在售票窗口买票,给了钱之后,就把身边的小明扣住,然后转身对售票大叔说,待会出票了你跟他说就行了,他会转告给我。于是,过一会,出结果了,小明就屁颠屁颠跑来说:“有结果了,出票成功.”

原理:上面的例子中小明就是回调载体。而小明是定义好的,我在我需要得到通知的事件中交给售票员的,并且在小明身上定义了一些协议,比如通知消息的格式等等。然后他就负责返回我要的消息。

对象:
我–>Me
售票员–>Conductor
小明–>Callback
.

实现代码

/**
 * 回调,这是小明
 * @Author TanXiongzhan
 */
public interface Callback {
    void returnResult(String msg);
}
/**
 * 售票员
 *
 * @Author Tan
 */
public class Conductor {

    public void printTickets(Callback callback) {

        System.out.println("售票员开始处理 . . . ");
        try {
            Thread.currentThread();
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("售票员处理完毕 . . . ");

        // 出票完成,通知出票结果(这里是发起回调的地方)
        callback.returnResult("出票完成");
    }
}
/**
 * 这是我
 * @Author Tan
 */
public class Me {

    // 指定一个售票人(待会他出票后要通知我)
    Conductor conductor = new Conductor();

    /*
     * 同步回调
     * 方法:买票
     * 内容:内容:把回调对象(小明)传给售票员
     */
    public void buyTicketsSyn(Callback callback) {
        conductor.printTickets(callback);
    }
    /*
     * 异步回调
     * 方法:买票
     * 内容:把回调对象(小明)传给售票员
     */
    public void buyTicketsSynASyn(Callback callback) {
        new Thread(new Runnable() {
            public void run() {
                conductor.printTickets(callback);
            }
        }).start();
    }
}
/**
 * 程序入口
 * @Author Tan
 */
public class Main {
    public static void main(String[] args) {
        // 定义一个回调
        Callback callback = new Callback() {
            @Override
            public void returnResult(String msg) {
                System.out.println("小明通知:" + msg);
            }
        };
        Me me = new Me();
        System.out.println("我准备买票----");
//        me.buyTicketsSyn(callback);           //发起买票(同步回调)
        me.buyTicketsSynASyn(callback);         //发起买票(异步回调)
        System.out.println("我在等待出票----");
    }
}

结果:
在这里插入图片描述
至此,一个简单的回调梳理就结束了。
在这里插入图片描述

自己写回调

现在通常都在spring 上开发,那么如何编写回调,并且给外部暴露回调接口呢?往下,进入进阶模式

实现说明:将回调实现抽象起来,然后暴露回调函数,其他地方需要重写回调时继承即可
然后将回调接口注入到spring 容器中即可。

简单比喻就是,我让小明出票了通知我,但是小明比较懒,就让小红来帮忙转达消息(小红继承小明,重写小明回调函数)

/**
 * 回调,这是一个小明
 * @Author TanXiongzhan
 */
public interface Callback {

    void returnResult(String msg);
}

/**
 * 将回调暴露出去,继承者重写结果返回方法即可
 * @Author Tan
 */
public abstract class CallbackAbstract implements Callback {

    @Override
    public void returnResult(String msg) {
//        System.out.println("小明通知:" + msg);
        returnResultPublic(msg);
    }

    public abstract void returnResultPublic(String msg);

}

/**
 * 第三方继承回调实现(监听回调)
 * 这是小红
 * @Author Tan
 */
@Service
public class CallbackImpl extends CallbackAbstract {

    @Override
    public void returnResultPublic(String msg) {
        System.out.println("小红通知:" + msg);
    }

}

/**
 * 售票员
 *
 * @Author Tan
 */
public class Conductor {

    public void printTickets(Callback callback) {

        System.out.println("售票员开始处理 . . . ");
        try {
            Thread.currentThread();
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("售票员处理完毕 . . . ");

        // 出票完成,通知出票结果(这里是发起回调的地方)
        callback.returnResult("出票完成");
    }
}


/**
 * 这是我
 * @Author TanXiongzhan
 */
public class Me {

    // 指定一个售票人(待会他出票后要通知我)
    Conductor conductor = new Conductor();

    /*
     * 同步回调
     * 方法:买票
     * 内容:内容:把回调对象(小明)传给售票员
     */
    public void buyTicketsSyn(Callback callback) {
        conductor.printTickets(callback);
    }

    /*
     * 异步回调
     * 方法:买票
     * 内容:把回调对象(小明)传给售票员
     */
    public void buyTicketsSynASyn(Callback callback) {
        new Thread(new Runnable() {
            public void run() {
                conductor.printTickets(callback);
            }
        }).start();
    }
}
/**
 * 在实际应用中,用注入的方式声明回调接口
 * 谁实现,调用谁的回调函数
 * @Author Tan
 */
@Service
public class MainSpring implements InitializingBean {

    @Autowired
    private Callback callback;

    @Override
    public void afterPropertiesSet() throws Exception {
        Me me = new Me();
        System.out.println("我准备买票----");
//        me.buyTicketsSyn(callback);           //发起买票(同步回调)
        me.buyTicketsSynASyn(callback);         //发起买票(异步回调)
        System.out.println("我在等待出票----");
    }
}

运行结果:
在这里插入图片描述
.
.
.
完毕

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cy谭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值