- 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()做了切片,從代碼中剝離出來,使代碼複用性更高,也更簡潔