看过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实现:
用这种回调模式方便的把openConnection()和closeConnection()做了切片,从代码中剥离出来,使代码复用性更高,也更简洁
Java代码
- 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实现:
Java代码
- 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()做了切片,从代码中剥离出来,使代码复用性更高,也更简洁