从Spring HibernateTemplate模板方法设计模式的实现谈起
概述
模板方法模式是GOF设计模式中很典型的设计模式,其意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用。Spring模板方法模式实际是模板方法模式和回调模式的结合,Spring几乎所有的外接扩展都采用这种模式,如JNDI,JMS,JCA的 CCI,JDBC,ORM中的Hiberate3、jdo、Toplink等扩展都采用模板方法模式来扩展。
经典的模板方法设计模式
开闭原则是指一个软件实体应该对扩展开放,对修改关闭。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。如图所示,面向接口编程,client只需调用Template接口中的execute方法,在AbstractTemplate抽象类的示例代码所示,实现execute()方法,但在execute()方法中制定所需的大的步骤,调用如subExecute1(),subExecute2(),subExecute3()方法来完成,但AbstractTemplate抽象类把subExecute1(),subExecute2()设置为抽象方法,由子类来实现,subExecute3()给出了缺省实现,也可由子类来覆盖,如SubTemplateImpl2类。
public abstract class AbstractTemplate implements TemplateInterface { public void execute() { subExecute1(); subExecute2(); subExecute3(); } protected abstract void subExecute1(); protected abstract void subExecute2(); protected void subExecute3() { } } |
-- HibernateTemplate提供的便利
-- 一般我们使用Session的时候,如果这个Session是通过SessoionFactory的openSession方法而来,那么我们需要通过Try-Catch-Finally代码块来讲Session以及Transaction操作包裹。这么做的目的主要有两方面:
1. 出现异常时及时回滚Transaction。
2. 无论出现异常与否都可以在Finally代码块里关闭Session。这种情况就如同使用JDBC通过Connection连接数据库的操作。
-- 但是在Hibernate中,Session有关数据库操作的方法很多,如果在每次使用这些Session方法时都写一遍Try-Catch-Finally代码块,我们的代码就会变得很不优雅。不符合面向对象复用的原则。
-- 使用HibernateTemplate(实际上Spring对包括JDBC在内的大部分持久化技术都做了Template的支持),也就是模板方法设计模式,就可以免去重复这些代码块的工作。而只需要集中于Session的方法调用就可以了。
-- HibernateTemplate的使用
-- 将HibernateTemplate交给Spring管理
-- 将HibernateTemplate实例注入程序
-- 调用HibernateTemplate执行Session方法
-- HibernateTemplate实现模板方法设计模式的原理
-- 从HibernateTemplate的save开始
-- 按照执行步骤查看executeWithNativeSession方法
-- doExecute方法
-- 下图中用黄色底色条标出的就是我们的匿名内部类对象。
-- doExecute方法回调了该对象的doInHibernate方法
-- 这里解释一下回调函数
-- 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
-- 但是在Java中并没有指针这种东西,所以使用了通过匿名内部类传递回调函数的办法。
-- 为什么要使用回调函数
因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
-- Java中使用回调函数的例子
在Java的listener模型中,一个事件发生,那么系统就会调用通过匿名内部类实现的handler,来做出响应。
-- 关于为什么匿名内部类使用方法的局部变量时,该变量需要声明为final的解释
-- 其实解释总结起来就是局部变量的生命周期太短,没有匿名内部类对象的生存周期长。所以必须将局部变量声明为final。从而该变量就不会被放在JVM存储区域的栈中,而会被放在方法区中,从而延长了生命周期,
-- The difference is between local (method) variables vs class member variables. A member variable exists during the lifetime of the enclosing object, so it can be referenced by the inner class instance. A local variable, however, exists only during the method invocation, and is handled differently by the compiler, in that an implicit copy of it is generated as the member of the inner class. Without declaring the local variable final, one could change it, leading to subtle errors due to the inner class still referring to the original value of that variable.
从Spring HibernateTemplate模板方法设计模式的实现谈起的更多相关文章
- Spring 事务模板方法设计模式
接上一篇文章 上一篇讲到了doGetTransaction方法 一.模板方法设计模式 这里涉及到了一个经典的设计模式:模板方法 如下图: AbstractPlatformTransactionMana ...
- 五、模板方法设计模式及在Spring中的应用
模板方法模式是一种行为型设计模式,具体定义网络上很多资源搜到本文不赘述. 如果字面理解比较抽象的话,那以生活中简单的行为为例:天热了,到了晚上妈妈都要将今天没有吃完的饭菜放入冰箱.将饭菜放入冰箱就是一 ...
- Spring中的设计模式
[Spring中的设计模式] http://www.uml.org.cn/j2ee/201301074.asp [详解设计模式在Spring中的应用] [http://www.geek521.c ...
- JDK和Spring中的设计模式
创建型 1)工厂方法 Collection.iterator() 由具体的聚集类来确定使用哪一个Iterator 2)单例模式 Runtime.getRuntime() 3)建造者模式 StringB ...
- 大话设计模式-->模板方法设计模式
在学习java的过程中,我们肯定听到过设计模式这名词,在行业中有这么一句话,若您能熟练的掌握23种设计模式,那么你便是大牛! 好了,废话不多说,今天我跟大家分享一下23种设计模式之一的 模板方法 设 ...
- Java抽象类深入理解-----模板方法设计模式(Templete Method)
模板方法设计模式(Templete Method) 定义一个操作中的算法骨架,而将一些可变部分的实现延迟到子类中. 模板方法设计模式使得子类可以不改变一个算法的结构即可重新定义该算法某些特定的步骤. ...
- Spring HibernateTemplate的使用
Spring HibernateTemplate的使用 2008-03-25 11:38 2020人阅读 评论(0) 收藏 举报 springbeanhibernatesessiondaoclass ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- Java设计模式——模板方法设计模式(abstract修饰)
解释: 一个抽象类中,有一个主方法,再定义 1...n 个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用. 解决的问题: 当功能内部一 ...
随机推荐
- centos用yum安装mysql-server
1.安装:#yum -y install mysql-server 2.修改配置:#vi /etc/my.cnf 暂时修改一下编码(添加在密码下方添加): default-character-set ...
- 伪装隐藏Nginx,PHP版本号提升服务器安全性
可能有时候我们看某些站点想知道别人在使用什么版本的web服务器之类的信息时,却发现并未显示版本号,甚至连WEB服务器都有变化,可以通过以下 方法来隐藏Nginx.PHP的版本号信息,来提升一定的安全性 ...
- CGAL Manual/tutorial_hello_world.html
Hello World Author CGAL Editorial Board 本教程是为知道C++和几何算法的基本知识的CGAL新手准备的.第一节展示了如何特化点和段CGAL类,以及如何应用几何谓词 ...
- Java学习-Overload和Override的区别
1.Overload是重载的意思,Override是覆盖的意思,也就是重写. 2.重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同). 3 ...
- 一个令人困惑的低效SQL
整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...
- 产生一个长度为100的int数组,并向其中随机插入1-100,不能重复
]; ArrayList myList=new ArrayList(); Random rnd=new Random(); ) { ,); if(!myList.Contains(num)) myLi ...
- 破坏之王——ddos攻击与防范 读书笔记
好久没写博客了,最近把绿盟的<破坏之王——ddos攻击与防范>又翻了一下,整理了关于DDOS分类和原理的xmind图~~ 百度云盘:http://pan.baidu.com/s/1i3ms ...
- Python之创建单元素tuple
tuple和list一样,可以包含 0 个.1个和任意多个元素. 包含多个元素的 tuple,前面我们已经创建过了. 包含 0 个元素的 tuple,也就是空tuple,直接用 ()表示: >& ...
- java 中 sleep(1000) 和 wait(1000) 的区别?
1.首先 sleep 方法是Thread类中的静态方法,他的作用是使当前线程暂时睡眠指定的时间,可以不用放在synchronized方法或者代码块中,但是 wait 方法是Object类的方法,它是使 ...
- App新版本提醒
童鞋们是否遇过在使用app的时候出现有新版本更新跳转到苹果商店的提示呢? github中有一个三方框架 Harpy 完美实现了这一功能! demo时刻 我的github - Harpy