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;
}
}
Java回調函數詳解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.