首页 > 编程语言 >Java回调机制研究

Java回调机制研究

时间:2022-11-11 14:35:50浏览次数:39  
标签:异步 调用 Java 函数 接口 机制 回调 public


1. 什么是回调函数

回调函数,顾名思义,用于回调的函数。回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数。回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机。回调函数包含下面几个特性:

(1)属于工作流的一个部分;
  (2)必须按照工作流指定的调用约定来申明(定义);
    (3)他的调用时机由工作流决定,回调函数的实现者不能直接调用回调函数来实现工作流的功能;

2.  回调机制

回调机制是一种常见的设计模式,它把工作流内的某个供,按照约定的接口暴露给外部使用者,为外部使用者提供数据,或要求外部使用者提供数据。

3.java的回调机制

软件模块之间总是存在这一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调、异步调用。

同步调用:一种阻塞式调用,调用方要等待对方执行完毕才能返回,它是一种单向调用;

回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口

异步调用:一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。

回调和异步调用的关系非常紧密:使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。

Java回调机制研究_回调机制

   我们暂且不讨论回调的一些名词和运行机制,首先说为什么会存在回调这样一种调用?同步和异步机制的出现不必多说,大家心知肚明,那回调机制为什么会出现呢?在我们现实生活中,有如下这样场景:有一位老板很忙,他没有时间盯着员工干活,然后他告诉自己的雇员,干完当前这些事情后,告诉他干活的结果。这个例子其实是一个回调+异步的例子,再举一个例子,A程序员写了一段程序a,其中预留了回调函数接口,并封装好了该程序,程序员B让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法,到这里你可能似懂非懂了,后面会继续说明回调的出现原因。接下来我们把上面例子变成代码,看到网上很多人最后搞混了异步和回调,因此例子中不加入异步调用。(注意:回调可不是解决什么调用时间过长问题,那是异步!)

首先创建一个回调接口,让老板得告知干完活如何找到他的方式:留下老板办公室地址:


package net.easyway.test;  

/**
* 此接口为联系的方式,不论是电话号码还是联系地址,作为
* 老板都必须要实现此接口
* @author Administrator
*
*/
public interface CallBackInterface {

public void execute();
}



创建回调对象,就是老板本人,因为员工干完活后要给他打电话,因此老板必须实现回调接口,不然员工去哪里找老板?


package net.easyway.test;  

/**
* 老板是作为上层应用身份出现的,下层应用(员工)是不知道
* 有哪些方法,因此他想被下层应用(员工)调用必须实现此接口
* @author Administrator
*
*/
public class Boss implements CallBackInterface {

@Override
public void execute() {
System.out.println("收到了!!" + System.currentTimeMillis());

}
}




  1. 创建控制类,也就是员工对象,他必须持有老板的地址(回调接口),即使老板换了一茬又一茬,办公室不变,总能找到对应的老板。


package net.easyway.test;  

/**
* 员工类,必须要记住,这是一个底层类,底层是不了解上层服务的
* @author Administrator
*
*/
public class Employee {

private CallBackInterface callBack = null;

//告诉老板的联系方式,也就是注册
public void setCallBack(CallBackInterface callBack){
this.callBack = callBack;
}

//工人干活
public void doSome(){
//1.开始干活了
for(int i=0;i<10;i++){
System.out.println("第【" + i + "】事情干完了!");
}

//2.告诉老板干完了
callBack.execute();
}
}




  1. 测试类代码:



package net.easyway.test;  

public class Client {

public static void main(String[] args) {


Employee emp = new Employee();

//将回调对象(上层对象)传入,注册
emp.setCallBack(new Boss());

//开启控制器对象运行
emp.doSome();
}

}




  1. 上面这个例子,大家可以和程序员A和程序员B的那个例子结合对照下。


看了上面的例子,有的人可能认为,这不是面向接口的编程吗?怎么会是回调,你再好好想想,咱们面向接口的编程的调用关系?在三层中,当业务层调用数据层时,是不需要把业务层自身传递到数据层的,并且这是一种上层调用下层的关系,比如我们在用框架的时候,一般直接调用框架提供的API就可以了,但回调不同,当框架不能满足需求,我们想让框架来调用自己的类方法,怎么做呢?总不至于去修改框架吧。许多优秀的框架提几乎都供了相关的接口,我们只需要实现相关接口,即可完成了注册,然后在合适的时候让框架来调用我们自己的类,还记不记得我们在使用Struts时,当我们编写Action时,就需要继承Action类,然后实现execute()方法,在execute()方法中写咱们自己的业务逻辑代码,完成对用户请求的处理。由此可以猜测,框架和容器中会提供大量的回调接口,以满足个性化的定制。

 

总之,要明确的一点是,首先要搞清回调函数出现的原因,也就是适用场景,才能搞清楚回调机制,不然事倍功半。

最后,再举一例,为了使我们写的函数接近完美,就把一部分功能外包给别人,让别人个性化定制,至于别人怎么实现不管,我唯一要做的就是定义好相关接口,这一设计允许了底层代码调用高层定义的子程序,增强程序灵活性,和反射有着异曲同工之妙,我觉得这才是回调的真正原因,以上是我个人一些理解,望讨论!

 

标签:异步,调用,Java,函数,接口,机制,回调,public
From: https://blog.51cto.com/u_15866446/5844845

相关文章

  • 大型CRM客户管理系统带小程序、H5 java源码(spring boot 后台 前端vue)
    CRM功能介绍1、系统管理:员工管理、角色管理、菜单管理、部门管理、岗位管理、字典管理、参数设置、日志管理2、系统监控:在线用户、定时任务、数据监控、服务监控3、系统工......
  • 上机题目(中级)- 将数组中的字符串按指定长度重新分割 (Java)
    题目如下:代码如下:packagehuawei;importjava.util.ArrayList;publicfinalclassDemo{/**功能:请编写一个函数,输入为一个字符串数组,*请按指定长度iInputLenth拆......
  • 上机题目(中级)- 两个超级大的整数相加相减 (Java)
    代码如下:publicclassAddSub{publicstaticvoidmain(String[]args){Stringa="4632864832684683568465765487657665765236465244";Stringb="47";i......
  • 上机题目(初级)- 下雪球(Java)
    上一节实现了滚雪球的代码,这一节实现下雪球的代码,简单考虑,制造一个循环,产生30个随机数,代码如下:importjava.awt.Color;importjava.awt.Frame;importjava.awt.Graphics;imp......
  • 如何通过Java 在 Word 中更改字体颜色
    在Word文档中使用不同的字体颜色既可以丰富文档外观,也能突出强调某些重点部分。当Word文档包含大量内容时,可以使用FreeSpire.DocforJava轻松更改Word文档中的字体颜色。......
  • java逻辑运算中 | | 和 | 的区别
    本文主要阐明逻辑运算中||(短路或)和|(逻辑或)的异同||和|的相同之处:只有二者都是假时,结果才为假,否则结果为true。||和|的不同之处在于:a||b:如果a为true......
  • java逻辑运算&&与&的区别
    本文主要阐述&&(短路与)和&(逻辑与)的运算异同:a&&b和a&b:共同之处是只有a和b同时为真时,结果才为真,否则为假不同点在于a&&b(短路与)若a为假时,则无需判断b,直接得出结......
  • 超全面Redis分布式高可用方案:哨兵机制
    开发工作中对于分布式缓存高可用方案(搭建Redis缓存高可用方案),Redis主从架构下是如何保证高可用的呢?我们知道RedisSentinel是一个分布式系统,为Redis提供高可用性解决......
  • [JavaScript-10]this指向
    1.默认绑定//全局环境指向windowconsole.log(this);//函数独立调用,函数内部this指向windowfunctionfn(){console.log(this);}fn();//函数当做对象方法......
  • Java--static 关键字小研究
    一、用static修饰的静态代码块:classDemo{{System.out.println("1、构造块。");}static{System.out.println("0、静态代码块。");}publicDemo(){Sys......