Java回调函数详解

来源:互联网 发布:php异步请求$.post 编辑:程序博客网 时间:2024/06/10 19:48



1、回调函数的简单实例


回调函数的简单说明:
对象A的方法funA把对象A的引用传递到对象B的方法funB里(且对象B方法funB的接收参数一般是对象A的实现接口),在对象B的方法funB中调用对象A的方法funC。对象A的方法funC被称为回调方法。






先上uml图:


 




可以使用回调函数的场景:
   1、在java里回调就是把对象A的引用传递到对象B的方法里,且对象B方法的接收参数一般是对象A的实现接口,所以对象B的方法里也只能调用到接口里的方法,不会暴露其他方法。
   2、如果对象B中需要执行保密的任务,
   3、如果对象B执行的操作需要花比较长的时间,这是A就可以单开一个线程来调度B,让B继续执行,且A可以做其他事情去。
   4、如果对象B可以抽象出来公共性的工作。
实例1:
参考网上打电话的例子: 这个例子采用异步加回调


这是一个调用接口
   public interface CallBack{
        /**
         这个是小李知道答案时要调用的函数告诉小王,也就是回调函数
        */
        public void solve(String result);
   }


   /*
   这个是小王,实现了一个回调接口CallBack,相当于对象A
   */
   public class Wang implements CallBack {
      private Li li;
      public Wang(Li li){
          this.li = li;
      }


      public void askQuestion(final String question){
      
       //这里用一个线程就是异步调用 
       new Thread(new Runnable(){
          @Override
          public void run(){
             li.executeMessage(this,question);
          }
       }).start();
       //问完问题了,可以做其他有意义的事情去了。
       play();
      }


    public void play(){
      System.out.println("做有意义的事情去了");
    }


    //回调函数,知道答案后就就可以通知小王了
    @Override
    public void solve(String result){
      System.out.println("小李通知小王的答案是:"+result);
    }
   }




/*
 这个是小李类,相当于对象B 
*/
  public class Li {


    public void executeMessage(CallBack callBack,String question){
       //小王问的问题是 
       System.out.println("小王问的问题是:"+question);
     
       System.out.println("小李思考->找到解决办法->获得答案");
       //把答案通知小王
       String result = "答案是ok";
       callBack.solve(result);
    }


  }


实例2:


UML类图:


 
接口:
import java.sql.Connection;
import java.sql.SQLException;




public interface ConnectionCallback<T> {


T doSql(Connection conn) throws SQLException;


}




异步+回调+匿名内部类:使用回调实现了公共性的工作。


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 执行数据库操作
 * 
 * execute database operation  
 */
public class DbHelper {

private static final Logger LOG = LoggerFactory.getLogger(DbHelper.class);

/**
* 执行数据库操作

* execute database operation  

* @param action
* @return
*/
public static <T> T execute(ConnectionCallback<T> action) {
Connection conn = null;
try {
conn = DbPool.getConnection();
return action.doSql(conn);
} catch (SQLException e) {
LOG.error(e.getMessage(),e);
} finally {
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
LOG.error(e.getMessage(),e);
}
}
return null;
}


/**
* 执行数据入库或更新删除操作

* execute database operation  

* @param sql
* @param args
* @return
*/
public static Integer executeUpdate(final String sql,final Object... args) {

return execute(new ConnectionCallback<Integer>() {

@Override
public Integer doSql(Connection conn) throws SQLException {

PreparedStatement pstmt = conn.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);

//        pstmt.setFetchSize(fetchSize);
   
   if (null != args) {
    StringBuilder sb = new StringBuilder(100);
     for (int i = 0; i < args.length; i++) {
       pstmt.setObject(i + 1, args[i]);
       sb.append(args[i]).append(",");
     }
//      System.out.println(sb);
   }


   LOG.info("SQL: " + pstmt);
   
   int result = pstmt.executeUpdate();
   
if(pstmt != null){
pstmt.close();
}


   return result;
}

});

}


/**
* 执行数据查询操作

* execute database operation  

* @param sql
* @param args
* @return
*/
public static List<Map<String,Object>> executeQuery(final String sql,final Object... args) {

return execute(new ConnectionCallback<List<Map<String,Object>>>() {

@Override
public List<Map<String,Object>> doSql(Connection conn) throws SQLException {
PreparedStatement pstmt = null;
try{
pstmt = conn.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);


pstmt.setFetchSize(50);

if (null != args) {
StringBuilder sb = new StringBuilder(100);
for (int i = 0; i < args.length; i++) {
pstmt.setObject(i + 1, args[i]);
sb.append(args[i]).append(",");
}
// System.out.println(sb);
}

LOG.info("SQL: " + pstmt);

ResultSet rs = pstmt.executeQuery();

return convertToList(rs);

}finally{
if(pstmt != null){
pstmt.close();
}

}
}

});

}



private static List<Map<String,Object>> convertToList(ResultSet rs) throws SQLException {


List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();


ResultSetMetaData md = rs.getMetaData();


int columnCount = md.getColumnCount();


while (rs.next()) {


Map<String,Object> rowData = new HashMap<String,Object>();


for (int i = 1; i <= columnCount; i++) {


rowData.put(md.getColumnName(i), rs.getObject(i));


}


list.add(rowData);


}
return list;


}
}




中间获取数据库连接的。




import java.sql.Connection;
import java.sql.SQLException;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import com.jolbox.bonecp.BoneCPDataSource;


/**
 * 数据库连接池
 * 
 * database connection pool (singleton)
 * 
 */
public class DbPool {


private static final Logger LOG = LoggerFactory.getLogger(DbPool.class);
private static volatile DbPool INSTANCE = null;
private static BoneCPDataSource dataSource = null;


// Private constructor suppresses default public constructor
private DbPool() {}


// thread safe and performance promote
public static DbPool getInstance() {
if (INSTANCE == null) {
synchronized (DbPool.class) {
// when more than two threads run into the first null check same  time, to avoid instanced more than one time, it needs to be checked again.
if (INSTANCE == null) {
INSTANCE = new DbPool();
setDataSource(new BoneCPDataSource());
}
}
}
return INSTANCE;
}


/**
* 这个需要手工关闭当你用过这个connection时

* this need to be closed by hand when you finished the query 

* @return connection
*/
@SuppressWarnings("static-access")
public static Connection getConnection() {
try {
return getInstance().getDataSource().getConnection();
} catch (SQLException e) {
LOG.error(e.getMessage(),e);
}
return null;
}



/**
* close db pool
*/
public void shutdown() {
if(getDataSource() != null){
getDataSource().close();
}
}


private static BoneCPDataSource getDataSource() {
return dataSource;
}


private static void setDataSource(BoneCPDataSource dataSource) {
DbPool.dataSource = dataSource;
}


}








   

0 0
原创粉丝点击