看过spring、hibernate源码的朋友对callback回调模式应该并不陌生,用一句话来概括就是:“if you call me, i will call back”,说白了,就是有相互依赖关系的两个类之间的互相调用,现在看看下面的代码模型:
上面的代码模型其原型是出自hibernate里的org.hibernate.jdbc.JDBCContext 和 org.hibernate.jdbc.ConnectionManager两个类,从上面的模型不难看出:Context类实现了A类的Callback接口,在Context类的构造器里将自己注入了A类,在Context类里调用A类的doIt()方法,这时就是:you call me;在doIt()方法体里调用了Context类的begin()和end()方法,这时就是:i call back。Context类 和 A类相互依赖,互相调用
在hibernate的源代码里大量使用了上面的callback回调模型,又如:org.hibernate.jdbc.JDBCContext 和 org.hibernate.impl.SessionImpl等等,可以自己去看源代码,这里不再赘述。
当然上面提到的模型中的两个类也可以写在同一个类里面,定义的Callback接口可以用内部匿名类来实现,比如下面的一个简单的dao实现:
- package com.cuishen.callback;
- public class Context implements A.Callback {
- private A a;
- public void begin() {
- System.out.println("begin ...");
- }
- public void end() {
- System.out.println("end ...");
- }
- public Context() {
- this.a = new A(this);
- }
- public void doSomething() {
- this.a.doIt();
- }
- public static void main(String args[]) {
- new Context().doSomething();
- }
- }
- package com.cuishen.callback;
- public class A {
- private final Callback callback;
- public static interface Callback {
- public void begin();
- public void end();
- }
- public A(Callback callback) {
- this.callback = callback;
- }
- public void doIt() {
- callback.begin();
- System.out.println("do something ...");
- callback.end();
- }
- }
上面的代码模型其原型是出自hibernate里的org.hibernate.jdbc.JDBCContext 和 org.hibernate.jdbc.ConnectionManager两个类,从上面的模型不难看出:Context类实现了A类的Callback接口,在Context类的构造器里将自己注入了A类,在Context类里调用A类的doIt()方法,这时就是:you call me;在doIt()方法体里调用了Context类的begin()和end()方法,这时就是:i call back。Context类 和 A类相互依赖,互相调用
在hibernate的源代码里大量使用了上面的callback回调模型,又如:org.hibernate.jdbc.JDBCContext 和 org.hibernate.impl.SessionImpl等等,可以自己去看源代码,这里不再赘述。
当然上面提到的模型中的两个类也可以写在同一个类里面,定义的Callback接口可以用内部匿名类来实现,比如下面的一个简单的dao实现:
- package com.cuishen.callback;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- public class Dao {
- private interface Callback {
- Object doIt(Connection conn) throws SQLException;
- }
- private Object execute(Callback callback) throws SQLException {
- Connection conn = openConnection(); // 开启数据库连接
- try { return callback.doIt(conn); } // 执行具体操作并返回操作结果
- finally { closeConnection(conn); } // 关闭数据库连接
- }
- public Object sqlQuery(final String sql) throws SQLException {
- return execute(
- new Callback() {
- public Object doIt(Connection conn) throws SQLException {
- return conn.createStatement().executeQuery(sql);
- }
- }
- );
- }
- public Connection openConnection() throws SQLException {
- return DriverManager.getConnection("", null);
- }
- public void closeConnection(Connection conn) throws SQLException {
- if(conn != null && !conn.isClosed()) {
- conn.close();
- }
- }
- }
用这种回调模式方便的把openConnection()和closeConnection()做了切片,从代码中剥离出来,使代码复用性更高,也更简洁
Java回调实现
有个这样的问题:老板(Boss)让工人(Worker)干完活告诉他干的情况如何。
实际上是一个典型的回调问题,Java实现如下:
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:18:33
* 事件接口
*/
public interface Event {
/**
* 返回发生事件信息
*
* @return 事件信息
*/
public String happendEvent();
}
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:18:33
* 事件接口
*/
public interface Event {
/**
* 返回发生事件信息
*
* @return 事件信息
*/
public String happendEvent();
}
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:18:14
* 事件A
*/
public class EventA implements Event {
/**
* 返回发生事件信息
*
* @return 事件信息
*/
public String happendEvent() {
return "发生了事件 EventA!";
}
}
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:18:14
* 事件A
*/
public class EventA implements Event {
/**
* 返回发生事件信息
*
* @return 事件信息
*/
public String happendEvent() {
return "发生了事件 EventA!";
}
}
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:18:21
* 事件B
*/
public class EventB implements Event{
/**
* 返回发生事件信息
* @return 事件信息
*/
public String happendEvent() {
return "发生了事件 EventB!";
}
}
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:18:21
* 事件B
*/
public class EventB implements Event{
/**
* 返回发生事件信息
* @return 事件信息
*/
public String happendEvent() {
return "发生了事件 EventB!";
}
}
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:20:48
* 工人
*/
public class Worker {
private Event event; //事件
private String name; //工人姓名
private Boss boss; //工人所属的老板
public Worker(String name, Boss boss) {
this.name = name;
this.boss = boss;
}
/**
* 干活
*/
public void doWork() {
System.out.println(name + " is doing working...");
//工人挺辛苦,干着枯燥乏味的重复工作,哈哈
for ( int i = 0; i < 2000000; i++) {
int x = i / 234 + 234;
}
System.out.println(name + " was finished work.");
//向老板说明发生的情况
boss.getWorkerEvent( this, event);
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:20:48
* 工人
*/
public class Worker {
private Event event; //事件
private String name; //工人姓名
private Boss boss; //工人所属的老板
public Worker(String name, Boss boss) {
this.name = name;
this.boss = boss;
}
/**
* 干活
*/
public void doWork() {
System.out.println(name + " is doing working...");
//工人挺辛苦,干着枯燥乏味的重复工作,哈哈
for ( int i = 0; i < 2000000; i++) {
int x = i / 234 + 234;
}
System.out.println(name + " was finished work.");
//向老板说明发生的情况
boss.getWorkerEvent( this, event);
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:26:22
* 老板
*/
public class Boss {
private String name;
public Boss(String name) {
this.name = name;
}
/**
* 老板接收工人的事件
* @param worker 工人
* @param event 事件
*/
public void getWorkerEvent(Worker worker, Event event) {
System.out.println( "老板接收到事件信息: "+worker.getName() + ": " + event.happendEvent());
}
}
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:26:22
* 老板
*/
public class Boss {
private String name;
public Boss(String name) {
this.name = name;
}
/**
* 老板接收工人的事件
* @param worker 工人
* @param event 事件
*/
public void getWorkerEvent(Worker worker, Event event) {
System.out.println( "老板接收到事件信息: "+worker.getName() + ": " + event.happendEvent());
}
}
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:35:38
* 测试类
*/
public class Test {
public static void main(String args[]){
//初始化老板和工人
Boss boss = new Boss( "老板");
Worker worker1= new Worker( "张三",boss);
Worker worker2= new Worker( "李四",boss);
//捏造两个事件
Event event1 = new EventA();
Event event2 = new EventB();
//事件是工人发出的
worker1.setEvent(event1);
worker2.setEvent(event2);
//工人干活,干完了通知老板干的情况如何
worker1.doWork();
worker2.doWork();
}
}
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-7-31 13:35:38
* 测试类
*/
public class Test {
public static void main(String args[]){
//初始化老板和工人
Boss boss = new Boss( "老板");
Worker worker1= new Worker( "张三",boss);
Worker worker2= new Worker( "李四",boss);
//捏造两个事件
Event event1 = new EventA();
Event event2 = new EventB();
//事件是工人发出的
worker1.setEvent(event1);
worker2.setEvent(event2);
//工人干活,干完了通知老板干的情况如何
worker1.doWork();
worker2.doWork();
}
}
运行结果:
张三 is doing working...
张三 was finished work.
老板接收到事件信息: 张三: 发生了事件 EventA!
李四 is doing working...
李四 was finished work.
老板接收到事件信息: 李四: 发生了事件 EventB!
Process finished with exit code 0
张三 was finished work.
老板接收到事件信息: 张三: 发生了事件 EventA!
李四 is doing working...
李四 was finished work.
老板接收到事件信息: 李四: 发生了事件 EventB!
Process finished with exit code 0
呵呵,工人干活完成后,自动将发生的事件汇报给老板。
当然,如果工人很多,每个人都汇报的话,老板肯定会烦,那么老板可能会下达,发生了严重问题的员工才需要汇报问题。这个时候,需要做个事件过滤。