`
生活的聆听者
  • 浏览: 17282 次
  • 性别: 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++将类的成员函数作为回调函数

    这是因为成员函数通常需要访问所属类的`this`指针来引用当前对象,而标准的回调机制往往期望的是一个全局或静态函数,而不是成员函数。 #### 非静态成员函数作为回调函数的挑战 在C++中,非静态成员函数不能直接...

    使用C语言写的回调函数

    回调函数在C语言中是一种非常重要的编程机制,它允许我们将一个函数的地址作为参数传递给另一个函数,由这个函数在适当的时候调用我们传入的函数。这种模式在处理异步事件、信号处理、排序算法以及其他需要在特定...

    C语言中的回调函数实例

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

    PB 回调函数,多线程

    总结来说,PB回调函数在多线程环境中的应用涉及到数据序列化、事件处理、线程安全以及组件化开发等多个方面。通过合理利用这些技术,可以构建高效、健壮的分布式系统或网络服务。而提供的"PBCallBack"资源则可以帮助...

    c++类成员函数作为回调函数

    在C++编程中,将类成员函数作为回调函数是一种常见的设计模式,特别是在处理异步操作、事件驱动编程或与库接口交互时。回调函数本质上是一个可以被其他代码调用的函数,它允许我们传递控制权给第三方代码并在特定...

    labview回调范例

    本篇将深入探讨“labview回调范例”,以及如何通过设置鼠标移动事件来触发回调函数,并利用引用更新主界面的控件。 首先,回调函数是当某个操作或事件发生时被调用的函数。在LabVIEW中,这种事件可以是按钮点击、...

    lwip的回调函数学习笔记与相关函数释疑

    在lwip中,回调函数是一种重要的机制,用于处理网络事件和数据传输。本文将详细介绍lwip的回调函数学习笔记与相关函数释疑。 一、tcp_listen 函数 tcp_listen 函数用于将一个 PCB 进入监听状态。当一个远端连接...

    VC++ DLL 实现回调函数的实例

    如果DLL和客户端可能在不同的线程中运行,确保回调函数是线程安全的,或者使用适当的同步机制,如互斥量或临界区。 通过以上步骤,你可以实现VC++中的DLL回调函数。这个简单的实例展示了如何在DLL和客户端之间传递...

    osg回调函数的使用

    在OSG中,回调主要通过两种方式实现:继承自特定的类并重写虚函数,以及使用Observer模式。例如,`osgGA::GUIEventHandler`类提供了一个用于处理图形用户界面事件的接口,你可以创建一个子类并重写`handle()`函数以...

    回调函数回调函数回调函数.txt

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

    C#调用C++动态库中自身定义的回调函数

    本主题将详细探讨如何在C#应用程序中调用C++动态链接库(DLL)中的函数,并且在这个过程中,C#能够注册和处理C++库中定义的回调函数。 首先,让我们理解回调函数的概念。回调函数是一种设计模式,允许将一个函数的...

    手动回调函数

    本篇文章将深入探讨回调函数的概念、用途,以及如何在VB中实现回调机制。 首先,让我们理解回调函数的基本概念。回调函数本质上是一个函数的引用,它被作为参数传递给另一个函数。当这个接收函数完成某些操作后,它...

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

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

    回调函数demo

    下面我们将深入探讨回调函数的概念、定义以及如何在实际代码中使用。 一、回调函数的概念 回调函数本质上是一个被其他函数调用的函数,它可以在适当的时候(如某个任务完成、条件满足时)执行。这种设计模式特别...

    java自定义回调函数

    Java自定义回调函数是软件开发中的一个重要概念,尤其是在Android和SDK开发中,它极大地提高了代码的灵活性和可扩展性。回调函数允许一个方法在完成特定操作后通知另一个方法,这种设计模式在异步编程和事件处理中...

    亲测可用,java 成功调用dll函数。包含调用回调函数,springboot版本。最近由于公司业务需要,要调用dll文件,用JNA调用。

    3. **回调函数**:在C/C++编程中,回调函数是指被其他函数调用的函数。在Java通过JNA调用DLL时,如果DLL函数需要一个回调函数作为参数,那么Java需要定义一个接口,该接口的方法将作为回调函数的实现,JNA会处理这个...

    回调函数应用.rar

    回调函数的应用非常广泛,包括异步处理、事件驱动编程以及数据处理等多个方面。 1. **异步编程**:在JavaScript中,由于其单线程特性,回调函数被用来处理异步任务,如网络请求、定时器等。当I/O操作完成时,回调...

    dll 回调函数

    回调函数在DLL中的应用广泛,例如在事件处理、数据传输、用户交互等场景。但需要注意的是,由于跨进程边界,回调函数可能会涉及到线程安全问题,因此在多线程环境中使用回调函数时,需要确保适当的同步措施。 在...

Global site tag (gtag.js) - Google Analytics