软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。
1 什么是回调
回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。
2、java实现回调
定义一个简单接口,并在该接口中声明我们要调用的方法。
假定我们希望在某个事件发生时得到通知。我们可以定义一个接口:
public interface InterestingEvent {
public void interestingEvent ();
}
这使得我们可以控制实现该接口的类的任何对象。因此,我们不必关心任何外部类型信息。 发出事件信号的类必须等待实现了 InterestingEvent 接口的对象,并在适当时候调用 interestingEvent() 方法。
public class EventNotifier {
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier(InterestingEvent event) {
ie = event; // 保存事件对象以备后用。
somethingHappened = false; // 还没有要报告的事件。
}
public void doWork() {
if (somethingHappened) { // 检查设置的谓词。
ie.interestingEvent();// 通过调用接口的这个方法发出事件信号。
}
}
public void setHappened(){//设置谓词。
somethingHappened=true;
}
}
在上例中,使用 somethingHappened 谓词来跟踪是否应触发事件。希望接收事件通知的代码必须实现 InterestingEvent 接口,并将自身引用传递给事件通知程序。
public class CallMe implements InterestingEvent {
@SuppressWarnings("unused")
private EventNotifier en;
public CallMe() {
// 注意 EventNotifier (InterestingEvent event),应该传递一个接口类型。
// 而下面将this,即实现了InterestingEvent接口的CallMe实例传递给
//EventNotifier。也就是所谓的接口回调了。
en = new EventNotifier(this); // 创建事件通知程序,并将自身引用传递给它。
}
// 为事件定义实际的处理程序。
public void interestingEvent() {
System.out.println("Call me Hello.");
}
}
下面写个测试类。
public class Test {
public static void main(String[] args) {
EventNotifier en=new EventNotifier(new CallMe());
en.setHappened();
en.doWork();
}
}
3、回调机制:
1.系统承诺发生什么事件时会执行什么接口的什么方法.
2.由对事件有兴趣的对象预先实现一个符合接口的具体行 为.注册到事件管理系统中,这样系统就有了一个指向这个接口的引用.
3.系统运行时由事件管理系统在事件发生时执行预定义的实现.
hibernateTemplate.execute(new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
/**
**实现hibernatecCallBack接口的类的,覆盖doInHibernate方法
**/
}
});
当hibernateTemplate调用execute方法时,会接收一个实现了HibernateCallBack接口的对象。并调用该对象的doInHibernate方法