`
lijiejava
  • 浏览: 262404 次
  • 性别: Icon_minigender_1
  • 来自: 南通
社区版块
存档分类
最新评论

Spring中的Template与Callback

阅读更多
http://yiben-tech.com/lmx/paper/59

Spring中 Callback模式和Template模式合用 随处可见。下面以常用的HibernateTemplate为例进行简要简述。
    由于java的JDBC的开发过程中有许多步骤是固定的(建立连接,执行操作,释放连接),因此spring采用模板方法对JDBC开发进行改进。模板方法定义过程的架构,一般是在一个抽象类中定义某个操作的一系列过程,将这一系列的过程中的变化部分以抽象方法的形式给出,子类在进行这个操作时,只需要继承该抽象类,重写该抽象方法即可。代码如下:
   
 public abstract class Ope{
    public final void step1(){..}
    public abstract  void step2();
    public final void step3(){…}
    public final void execute(){
        step1();
        step2();
        step3();
    }
}

public class MyOpe extends Ope{
   public void step2(){…}
   //public final void execute(){
        //step1();
        //step2();
        //step3();
   //}
}


这样,每一个具体的操作只需要实现step2()方法即可。

但是如果仅仅采用模板方法,就意味着每次进行增删改查操作,都需要继承某个类,在java开发中通常会频繁操作数据库,这种方法会显得十分的不方便。通常我们利用HibernateTemplate进行数据库操作时,是采用类似ht.save(…)的方式,在一个模板类中实现了所有的方法,而这其中用到了Callback模式。在HibernateTemplate模板类中有一个核心的方法,这个核心的方法完成相关的流程操作,其中的具体步骤通过回调传入的对象来完成(这个对象就是实现了Callback接口的类)。该类中的其它的方法(如save,update等)会通过Callback模式,调用这个核心的方法实现来完成最终的操作。这样就不需要实现多个类,只需在一个模板类中就可以完成全部的方法定义
    HibernateCallback接口的代码如下:
 
public interface HibernateCallback<T> {
   T doInHibernate(Session session) throws HibernateException, SQLException;
}

它只有一个方法doInHibernate 。HibernateTemplate中的方法,如save(),update()的具体实现都采用匿名类的方式实现了该接口,在doInHibernate中完成具体的操作。以save()方法为例:
public Serializable save(final Object entity) throws DataAccessException {
	return executeWithNativeSession(new HibernateCallback<Serializable>() {
      public Serializable doInHibernate(Session session) 
        throws HibernateException {
        checkWriteOperationAllowed(session);
        return session.save(entity);
			}
		});
	}

   save方法在doInHibernate方法中完成了session.save(entity)完成保存操作,而executeWithNativeSession方法可以看做是HibernateTemplate中的核心方法(它内部调用了doExecute()方法,doExecute()方法才是真正的核心方法,它完成了一系列操作)
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
			throws DataAccessException {

		Assert.notNull(action, "Callback object must not be null");

		Session session = (enforceNewSession ?
				SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());
		boolean existingTransaction = (!enforceNewSession &&
				(!isAllowCreate() || 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 =
					(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
			T 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());
				}
			}
		}
	}


spring中的JdbcTemplate等都采用了相同的方法。
3
1
分享到:
评论
3 楼 sinye 2011-08-18  
写的非常棒,这篇文章可以很快的理解模板和回调!在模板讲解例子中,其实继承的那个类不需要再重写excute()方法了,而且也不能重写,因为是final的,只需实现step2()方法就Ok了。楼主研究过Hibernate的源码啊?
2 楼 cn-done 2011-08-17  
liuyexing1986 写道
对回调的理解不够深刻,楼主可以讲一下,这里面哪个地方进行了回调吗

  T result = action.doInHibernate(sessionToExpose); 
1 楼 liuyexing1986 2011-07-20  
对回调的理解不够深刻,楼主可以讲一下,这里面哪个地方进行了回调吗

相关推荐

    Spring Dao层设计

    Spring 数据库访问的支持。包括统一异常体系和Spring的Template+CallBack的解读

    59丨模板模式(下):模板模式与Callback回调函数有何区别和联系?1

    例如,Spring框架中的`JdbcTemplate`虽然名字中含有“Template”,但它其实主要依赖于回调机制。`JdbcTemplate`执行SQL查询时,会调用用户提供的回调方法来处理结果集,这类似于同步回调,因为结果处理在查询完成后...

    JdbcTemplate教程

    除了大量使用Template Method来封装一些底层的操作细节,spring也大量使用callback方式类回调相关类别的方法以提供JDBC相关类别的功能,使传统的JDBC的使用者也能清楚了解spring所提供的相关封装类别方法的使用。

    spring-data-redis_exm

    《深入浅出Spring Data Redis:连接池与事务实践》 Spring Data Redis是Spring框架的一个重要模块,它为Redis提供了丰富的支持,使得在Java应用中使用Redis变得更加便捷。本篇文章将详细探讨Spring Data Redis的...

    Spring的DAO

    Spring的DAO设计模式主要体现在模板(Template)和回调(Callback)两个概念上。 模板类,如`JdbcTemplate`,负责处理数据访问流程中的通用部分,包括事务管理、资源的打开和关闭,以及异常的处理。这些模板类通常...

    Spring JdbcTemplate api

    在`JdbcTemplate`的设计中,模板(Template)承担着事物控制、资源管理和异常处理的责任,而回调(Callback)则专注于实现应用程序特有的逻辑,如创建SQL语句、设置参数和处理结果集。这种分离使得开发者能够更专注...

    Spring+JMS+消息处理

    Spring JMS框架是Spring项目的一部分,其主要目标是简化Java Message Service (JMS) API的使用,使得开发人员能够更容易地与消息中间件进行交互。通过Spring JMS,开发者可以更加专注于业务逻辑而非底层的消息传递...

    snypir-callback-prototype

    SnypirCallbackPrototype Snypir.com的Android应用未完成的原型 如果您将AndroidAnnotations与Spring Rest Template一起使用,这就是您的应用程序的外观。

    weixin-java-cp-demo:基于Spring Boot和WxJava实现的微信企业号企业微信放置演示

    本项目为WxJava的Demo演示程序,基于Spring Boot ,实现企业微信替代开发功能。 更多信息请查阅: : 使用步骤: 请注意,本演示为简化代码编译时加入了lombok支持,如果不了解lombok的话,请先学习下相关知识,可以...

    compass-reference.pdf

    #### Template and Callback 模板和回调机制提供了额外的灵活性,允许开发者定义自己的数据处理逻辑,比如自定义索引创建流程或查询优化策略。 ### 配置 #### Programmatic Configuration 通过编程方式配置Compass...

    oauth2github

    在这个场景中,我们探讨的是如何将你的应用程序与GitHub的OAuth2服务集成,以便用户可以通过他们的GitHub账户安全地登录你的应用。 首先,我们需要在GitHub上为你的应用程序创建一个OAuth2客户端。这涉及到以下几个...

    程序员英语单词册

    - 示例:Spring 框架是一种广泛使用的 Java 应用程序开发框架。 3. **Architecture (架构、系统架构/体系结构)** - 定义:描述了系统的整体结构以及各个组成部分之间的关系。 - 示例:微服务架构是一种将单一...

Global site tag (gtag.js) - Google Analytics