spring中使用了回调函数

本文深入探讨了Spring框架中回调函数的使用方式,并通过具体代码示例详细解释了其工作原理,帮助读者理解如何利用回调函数简化数据库操作。

spring中使用了回调函数:我看到许多人对于这个回调函数的使用不知如何去理解,通过看源码,这里我谈下自己的观点

 

1.spring中的回调函数例子:

如:

((Integer)getHibernateTemplate().execute(new HibernateCallback() {
        public Object doInHibernate(Session session) throws HibernateException {
         int i=0;
         Statement st = null;
        
         System.out.println("session==================="+session);
         try{
            Connection con = session.connection();
            st = con.createStatement();
log.debug("exec sql:"+sql);           
            i=st.executeUpdate(sql);
          }catch (SQLException ex) {
           //System.out.println("inin================="+ex.getMessage());
           throw new DataAccessResourceFailureException(ex.getMessage());
         

          }finally{
           try {
      st.close();
     } catch (SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
          }
          return new Integer(i);
        }
      })).intValue();
  

 

然后------------

public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
  Assert.notNull(action, "Callback object must not be null");

  Session session = getSession();
  boolean existingTransaction = SessionFactoryUtils.isSessionTransactional(session, getSessionFactory());
  if (existingTransaction) {
   logger.debug("Found thread-bound Session for HibernateTemplate");
  }

  FlushMode previousFlushMode = null;
  try {
   previousFlushMode = applyFlushMode(session, existingTransaction);
   enableFilters(session);
   Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
   Object result = action.doInHibernate(sessionToExpose);//这里就是回调接口中的方法
   flushIfNecessary(session, existingTransaction);
   return result;
  }
  catch (HibernateException ex) {
   throw convertHibernateAccessException(ex);
  }
  catch (SQLException ex) {
   throw convertJdbcAccessException(ex);
  }
  catch (RuntimeException ex) {
   // Callback code threw application exception...
   throw ex;
  }
  finally {
   if (existingTransaction) {
    logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
    disableFilters(session);
    if (previousFlushMode != null) {
     session.setFlushMode(previousFlushMode);
    }
   }
   else {
    // Never use deferred close for an explicitly new Session.
    if (isAlwaysUseNewSession()) {
     SessionFactoryUtils.closeSession(session);
    }
    else {
     SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
    }
   }
  }
 }
-------------------------解释下这里的回调-----------------

就是系统调用execute()方法,这时候因为execute()方法需要一个接口类型的参数,那么如何给他一个这样的参数呢,方式好几种,这里采用的是匿名内部类的实现方式,最后execute得到了需要的参数后,再调用传给它的接口的方法。

 

如果还不明白举个生动的例子:

 

我有个问题需要问你,这时候我打电话给你,这个就相当主调函数,但是你需要思考一下答案才能回答我,我就只有把号码给你了,第二天你想到了答案在打电话给我说答案,就相当于是回调了

这里的execute就是回调函数,他需要我给他一个参数,然后它再去调用

### 关于Spring框架中的回调函数Spring框架中,回调机制被广泛应用于各种场景。通过接口定义抽象行为,并允许具体的实现类提供具体的行为逻辑。 #### 使用`ApplicationListener`作为事件监听器 一种常见的回调方式是在应用程序上下文中注册事件监听器。当特定类型的事件发生时,会自动调用这些监听器的方法: ```java @Component public class MyEventListener implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { System.out.println("Received custom event: " + event.getMessage()); } } ``` 此类实现了`ApplicationListener<T>`接口并重写了`onApplicationEvent()`方法,在该方法内部可以处理接收到的事件实例[^1]。 #### 利用`SmartLifecycle`管理组件生命周期 对于希望控制其启动和关闭过程的服务组件来说,可以通过继承自`SmartLifecycle`来设置回调钩子: ```java @Component public class MyService implements SmartLifecycle { private volatile boolean running = false; @Override public void start() { // 启动服务所需的初始化操作 running = true; } @Override public void stop() { // 停止服务前执行清理工作 running = false; } @Override public boolean isRunning() { return running; } } ``` 这里定义了一个名为MyService的服务bean,它会在容器刷新完成后由Spring自动调用start()方法完成必要的准备工作;同样地,在销毁之前也会触发stop()[^2]。 #### 结合AOP切面编程技术 面向方面编程(Aspect-Oriented Programming,AOP)也是实现回调的一种有效手段之一。借助@AfterReturning,@Around等注解可以在目标方法前后插入额外的功能模块: ```java @Aspect @Configuration public class LoggingAspect { @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods(){} @Before("serviceMethods()") public void logBefore(JoinPoint joinPoint){ System.out.println("Method Name : "+joinPoint.getSignature().getName()); } @AfterReturning(pointcut="serviceMethods()", returning="result") public void logAfterReturning(Object result){ System.out.println("Return Value :"+result); } } ``` 上述代码片段展示了如何利用AOP特性拦截指定包下的所有业务层方法,并在其执行前后打印日志信息[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值