`
生活的聆听者
  • 浏览: 16693 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

函数回调机制浅析以及Spring框架中对函数回调的经典应用

 
阅读更多
  • 回调函数的概念

       回调函数顾名思义就是:A调用B,然后B又可以回调A中的方法。可以举如下例子:晚上下班回家开灯准备用电饭煲煮晚饭,发现家里由于欠费导致停电了,这个时候通过支付宝缴纳电费,电费缴纳成功之后呢支付宝需要通知电力公司,我家的电费缴纳成功了,然后我查看家里的电表,发现电费缴纳成功,可以继续做饭了(只是举例说明回调函数的含义,具体支付宝缴纳电费不一定是这么实现)。

 

  • 样例代码

回调接口,电费缴纳成功之后需要通知客户端调用方,说电费缴纳成功了。

package com.test;

/**
 * 回调接口
 */
public interface ICallBackAction {
    void doOnLight(int number);
}

 

 具体缴纳费用的接口

/**
 * 缴纳费用的接口
 */
public interface IPayFees {

    void executor(ICallBackAction action);
}

 

 缴纳电费的具体实现类,客户端调用此方法缴纳电费,缴纳成功之后需要回调客户端传入的回调函数的类对象实例中的方法,简称回调函数。

package com.test;

/**
 * 缴纳电费的实现模板类
 */
public class PayElectricityFeesTemplate implements IPayFees{

    private int money ; 
    
    public PayElectricityFeesTemplate(int money) {
        this.money = money;
    }
    
    @Override
    public void executor(ICallBackAction action) {
        System.out.println("缴纳电费" + money + "元");
        System.out.println("0.5元一度电,共" + money * 2 + "度电, 充值成功");
        action.doOnLight(money * 2);
    }

    
}

 测试类

package com.test;

public class CallBackMain {

    public static void main(String[] args) {
        final CallBackMain main = new CallBackMain(); 
        System.out.println("开始用电饭锅煮午饭..........");
        System.out.println("发现家里断电了,发现是两个月没有充电费,欠费了..........");
        System.out.println("开始充电费");
        main.doBeginPayFee(100);
    }
    
    
    
    private void doBeginPayFee(int money) {
        
        IPayFees instance = new PayElectricityFeesTemplate(money);
        instance.executor(new ICallBackAction(){
           //具体的回调函数,又被调用方在执行完具体逻辑之后调用此方法。还可以将被调用
           //方法中的相关参数传递给调用方
            @Override
            public void doOnLight(int number) {
                System.out.println("电费充值成功,来电了,共剩" + number + "度电");
            }
        });
    }
}

 

 

  • Spring中JdbcTemplate应用

    JdbcTemplate.java为Spring中关于数据库操作的模板类,主要用于数据库操作的相关功能,例如获取

    数据库的连接、超时处理等公共逻辑的模板类。

org.springframework.jdbc.core.JdbcTemplate.java


        /**
         * execute方法主要用于调用方需要执行数据库操作时的执行入口
         * 此方法会统一获取数据库的底层连接,然后通过回调接口回传给调用方执行具体的数据库
         * 操作。
         * 这样做的好处是将获取数据库的连接操作统一封装到模板类中,调用方无需显示获取数据库
         * 连接而是通过回调函数回传connection去操作数据库。这样代码即达到了复用,也达到有解耦
         * 的效果,调用方只需要关心自己的执行业务即可。
         */
	@Override
	public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Connection con = DataSourceUtils.getConnection(getDataSource());
		try {
			Connection conToUse = con;
			if (this.nativeJdbcExtractor != null) {
				// Extract native JDBC Connection, castable to OracleConnection or the like.
				conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
			}
			else {
				// Create close-suppressing Connection proxy, also preparing returned Statements.
				conToUse = createConnectionProxy(con);
			}
			return action.doInConnection(conToUse);
		}
		catch (SQLException ex) {
			// Release Connection early, to avoid potential connection pool deadlock
			// in the case when the exception translator hasn't been initialized yet.
			DataSourceUtils.releaseConnection(con, getDataSource());
			con = null;
			throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
		}
		finally {
			DataSourceUtils.releaseConnection(con, getDataSource());
		}
	}

 

org.springframework.jdbc.core.simple.AbstractJdbcInsert.java

/**
	 * Delegate method to execute the insert, generating any number of keys.
	 */
	private KeyHolder executeInsertAndReturnKeyHolderInternal(final List<?> values) {
		.........
                .........
			else {
		  getJdbcTemplate().execute(new ConnectionCallback<Object>() {
	                            /**
                                     * 注意参数conn对象,此对象为被调用方通过回调函数
                                     * 传入的值,这样调用方只需要关心自己的数据库操作业务。
                                     */                                       @Override
					public Object doInConnection(Connection con) throws SQLException, DataAccessException {
						// Do the insert
						PreparedStatement ps = null;
						try {
							ps = con.prepareStatement(getInsertString());
							setParameterValues(ps, values, getInsertTypes());
							ps.executeUpdate();
						}
						finally {
							JdbcUtils.closeStatement(ps);
						}
						//Get the key
						Statement keyStmt = null;
						ResultSet rs = null;
						Map<String, Object> keys = new HashMap<String, Object>(1);
						try {
							keyStmt = con.createStatement();
							rs = keyStmt.executeQuery(keyQuery);
							if (rs.next()) {
								long key = rs.getLong(1);
								keys.put(getGeneratedKeyNames()[0], key);
								keyHolder.getKeyList().add(keys);
							}
						}
						finally {
							JdbcUtils.closeResultSet(rs);
							JdbcUtils.closeStatement(keyStmt);
						}
						return null;
					}
				});
			}
			return keyHolder;
		}
		return keyHolder;
	}

 

总结:

    回调函数不只是有同步,也可以做到异步操作,这里就不举例说明,大体模式是一样的。

分享到:
评论

相关推荐

    回调函数回调函数回调函数

    回调函数 回调函数 回调函数 回调函数 回调函数 回调函数

    回调函数回调函数回调函数回调函数回调函数回调函数

    回调函数回调函数回调函数回调函数回调函数回调函数

    C语言中的回调函数实例

    在C语言中一般用typedef来为回调函数定义别名(参数名)。 别名通过宏定义typedef来实现,不是简单的宏替换。可以用作同时声明指针型的多个对象。 比如: 代码如下:char *pa,pb;//pa是一个char型指针,但pb是一个...

    C# 实现回调函数

    C# 实现回调函数C# 实现回调函数C# 实现回调函数C# 实现回调函数C# 实现回调函数

    C++回调函数详解

    我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理、用回调函数记录某操作进度等)变得非常方便和符合逻辑,那么它的内在机制如何呢,怎么定义呢?它和其它函数(比如钩子函数)有何不同呢?...

    回调函数的应用

    回调函数的应用,了解回调函数的用法学习回调函数的思想

    C++中回调函数(CallBack)的用法分析

    本文实例分析了C++中回调函数(CallBack)的用法。分享给大家供大家参考。具体分析如下: 如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。 其错误是普通的C++成员函数都隐含了一个传递...

    如何让类的成员函数作为回调函数

    如何让类的成员函数作为回调函数 回调函数大家都懂得 需要了解下

    BCB线程中调用主界面的回调函数

    网上的回调函数都是API例子,学习函数指针倒是不错,可是很难让初学者立即应用。常见的情况是辅线程完成某事件后需要“通知”主界面,比如常见的进度条——线程中完成一定的进度后即通知主界面显示到一定的刻度。本...

    mfc下实现回调函数

    程序实现了在mfc下如何定义一个回调函数,如何使用回调函数,以及如何把类指针传递递给用户回调函数的例程。

    C++将类的成员函数作为回调函数

    C++将类的成员函数作为回调函数使用介绍

    js回调函数的使用技巧和认识

    js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数js回调函数...

    ribbon回调函数大全资料.xlsx

    ribbon回调函数大全资料

    CC++中回调函数初探

    对于很多初学者来说,往往觉得回调函数很神秘,很想知道回调函数的工作原理。本文将要解释什么是回调函数、它们有什么好处、为什么要使用它们等等问题,在开始之前,假设你已经熟知了函数指针。    什么是回调...

    使用C语言写的回调函数

    一个使用C语言写的回调函数 包括函数的调用,函数的取消等操作。

    回调函数被连续执行两次或多次的原因

    回调函数被连续执行两次或多次的原因: 根本原因:回调函数的事件预订【+=】语句被执行了两次或多次。 实例:移动web页的代码页类MobileDefault的Page_Init事件过程,包含的InitializeComponent()连续出现了两次...

    C回调函数,函数回调

    程序员常常需要实现回调。本文将讨论函数指针的基本原则并说明如何使用函数指针实现回调。注意这里针对的是普通的函数,不包括完全依赖于不同语法和语义规则的类成员函数(类成员指针将在另文中讨论)。

    Delphi中制作DLL中回调函数的应用

    扩展,在面向对像中的回调,其实是指面向对像中类对像的事件,事件就是原始的回调函数。面 向对像, 将回调函数定义成事件过程,在程序引用对像时,若指定了对像的过程事件后,那么在 要进行事件触发的地方检查事件...

    经典回调函数实例

    经典回调函数朋友打电话示例,详细描述了回调函数的工作机制。

    c++ qt 中在静态函数中发信号的方式,以及回调函数的基本使用,

    c++ qt 中在静态函数中发信号的方式,以及回调函数的基本使用

Global site tag (gtag.js) - Google Analytics