`
longgangbai
  • 浏览: 7252717 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate的拦截器和监听器

阅读更多

项目采用Spring构建,持久层技术采用的是 JPA规范 + Hibernate实现的方案
要实现审计日志的需求,我试用了多种技术方案,最终确定了采用Hibernate 3的新特性事件驱动架构来解决:

技术选型:

  1. 最土的,在所有的Dao方法中显示的编写日志记录代码
    该项目以前是用.net这么干的,这种做法重复工作量太大,维护性差,并且也没实现字段级变更的记录,根本不予考虑。

  2. 数据库触发器 - 与数据库耦合
    与数据库耦合,违背了使用hibernate的初衷,也不予考虑

  3. 原生的Hibernate Interceptor
    优点:可以在hibernate对象操作的时候获取最为详细的运行期信息,字段名,原始值,修改后值等等。
    缺点:在JPA  API的封装下很难获取到hibernate的session,不能进行持久化操作。

  4. JPA callback / event-listener
    优点:JPA规范,最为优雅简单
    缺点:功能太弱,不能满足需求

  5. 很自然地,干这种事AOP似乎比较合适
    优点:灵活,在spring容器中,可以访问所有spring bean
    缺点:不能获取详细的运行期信息(字段名,原始值,等等),无法感知hibernate的事务执行,即使dao事务rollback,仍然会插入一条操作历史记录,破坏了“操作”和“历史”的一致性。

  6. 采用Hibernate 3的新特性 Event-listener
    可以解决以上所有问题
    能够取得运行期详细信息,除了能记录粗粒度的实体的保存删除操作外,还能精确追踪对实体字段修改、实体关联/级联关系的变更,能记录更新前的值、更新后的值,可以生成详细日志。
    灵活解耦,跨数据库,不影响原有代码。

    Hibernate3 新特性事件处理框架是hibernate 2拦截器的一个补充或者替代,由拦截器被动拦截操作事件变成事件源的主动驱动,这是一个进步。Hibernate 事件框架官方文档.

    Hibernate3中定义了很多的事件,涵盖了持久化过程中不同的生命周期。简单说Session的一个方法(load, flush...)分别对应一个事件,当该方法被调用时,就会触发一个相应的事件,这个事件会被我们预先定义的事件监听器收到,再进行相应的处理。这种方式来做审计日志是再适合不过。

    但也有个缺点就是这样的Event-listener是脱离主容器(比如Spring IoC环境)单独实例化的,无法访问主容器的资源(比如要取得当前登录的用户信息就会比较麻烦)。这个暂时还没解决。

在这里我们选取PostInsertEventListener(插入后事件),PostUpdateEventListener(更新后事件),PostDeleteEventListener(删除后事件)接口作为CRUD方法的监听接口。hibernate3中事件是分为pre和post,表示该发生事件前、后。这里我们全部用Post,因为PostEvent只有在数据实际改变后才会触发,假如CRUD事务因为异常回滚,则不会触发事件。

首先定义一个mark接口Historiazable,实现该接口的entity类表明是需要做审计日志的。
然后编写我们自定义的EventListener类,实现上述的事件接口。
在事件接口实现方法里在根据不同的事件编写审计日志的代码。

 

public class HistoryListener implements PostInsertEventListener,
        PostUpdateEventListener, PostDeleteEventListener {
  
    @Override
    public void onPostInsert(PostInsertEvent event) {
        if (event.getEntity() instanceof Historizable) {
        //  保存 插入日志
        }
    }

    @Override
    public void onPostUpdate(PostUpdateEvent event) {
        if (event.getEntity() instanceof Historizable) {
        // 保存 修改日志
        }
    }

    @Override
    public void onPostDelete(PostDeleteEvent event) {
        if (event.getEntity() instanceof Historizable) {
        // 保存 删除日志
        }
    }
}

配置EventListener
编辑hibernate.cfg.xml,配置监听器

    <session-factory>
        <listener type="post-insert" class="net.jeffrey.hibernate.history.HistoryListener"/>
        <listener type="post-update" class="net.jeffrey.hibernate.history.HistoryListener"/>
        <listener type="post-delete" class="net.jeffrey.hibernate.history.HistoryListener"/>
    </session-factory>

 

配置持久化单元
在persistence.xml中加入
 <property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"/>
这样JPA环境启动后,就会正确装载初始化自定义的事件监听器。

源代码:
详细的代码请下载源代码,有完整的注释和单元测试用例,一看就明白了。
为了简便起见,没有建立spring或者ejb3项目,使用的是POJO方式,但都是一样的。

在源码根目录里的data.sql是为单元测试准备的基础数据,请在测试前导入到数据库中

源码是Netbeans项目,需要添加Hibernate的依赖和mysql驱动
在http://www.hibernate.org/6.html 下载最新版的Hibernate Core, Hibernate Annotations和
Hibernate EntityManager。解压缩后将lib里所有的jar添加到项目中(注意不要把ant相关jar添加进去,可能会导致netbeans无法正常构建项目)。

分享到:
评论

相关推荐

    拦截器和控制器的区别

    拦截器和过滤器的区别 1、拦截器基于动态代理 , 过滤器基于函数回调 2、拦截器不依赖于servlet容器,通过动态代理实现,过滤器依赖于servlet容器 3、拦截器在方法前后,异常前后等调用,而过滤器只能在请求前和请求...

    Hibernate实战(第2版 中文高清版)

     12.3.4 实体监听器和回调   12.4 小结   第13章 优化抓取和高速缓存   13.1 定义全局抓取计划   13.1.1 对象获取选项   13.1.2 延迟的默认抓取计划   13.1.3 理解代理   13.1.4 禁用代理生成   ...

    前后台管理系统模板源代码 java语言 ssh开发框架 Spring+Struts+Hibernate

    又实现了权限拦截器、项目监听器、单元测试等功能。 页面简洁大气美观,系统耦合度小,可配置度高,几乎包含了全部常用功能,是很好的学习和使用框架,可直接部署测试。 项目访问路径:...

    从零开始学Spring Boot

    1.25 Spring Boot 拦截器HandlerInterceptor 1.26 Spring Boot启动加载数据CommandLineRunner 1.27 Spring Boot环境变量读取和属性对象的绑定 1.28 Spring Boot使用自定义的properties 1.29 改变自动扫描的包 1.30 ...

    传智播客黑马35期

    day21_监听器 day22_文件上传与下载 day23_基础加强 day24_在线支付&JavaMail; day25_编码实战day01 day26_编码实战day02 day27_编码实战day02 day28_struts2基础 day29_struts2加强 day30_struts2拦截器&...

    java后台框架源码

    listener:目前只有session的监听器,用于监听session的 service:具体的业务处理包 util:项目工具包 vo:存放业务结果数据的,响应页面的json对象就存放在里面ResultData类里面 conf文件:系统配置的文件 ...

    从J2SE到J2EE知识点介绍

    1. struts2的拦截器定义以及使用 153 2. struts标签 160 3. Struts 2 标签库说明及使用 160 4. set 描述 169 5. text 描述 170 6. property 描述 170 7. Struts的异常处理 171 8. Struts的上传与下载 178 五、 ...

    ssh对lob完美处理

    structs1.2 spring2.5 hibernate3.0 java web 对clob大文本 blob图像处理 这是一个完整的例子,整合了ckeidtor,servlet直接显示...配置了监听器,SPRING事物管理,structs1.2拦截器配置 如果有疑问联系QQ:766591490

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    10.8 实体的生命周期和监听器 444 10.8.1 实体的生命周期与回调事件 444 10.8.2 使用专门的监听器实现回调 448 10.8.3 为全部实体配置默认监听器 450 10.8.4 排除监听器 452 10.9 本章小结 455 第11章 JPA的查询支持...

    spring in action英文版

     11.1.1 安全拦截器  11.1.2 认证管理器  11.1.3 访问决策管理器  11.1.4 运行身份管理器  11.2 管理身份验证  11.2.1 配置ProviderManager  11.2.2 根据数据库验证身份  11.2.3 根据LDAP...

    Spring in Action(第2版)中文版

    11.3.4使用注释声明拦截器 11.4小结 第12章访问企业服务 12.1从jndi中获取对象 12.1.1使用传统的jndi 12.1.2注入jndi对象 12.1.3在spring2中注入jndi对象 12.2发送电子邮件 12.2.1配置邮件发送器 12.2.2...

    Spring in Action(第二版 中文高清版).part2

    11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送...

    Spring in Action(第二版 中文高清版).part1

    11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送...

    Spring.3.x企业应用开发实战(完整版).part2

    12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务处理 12.2.8 延迟加载的问题 12.3 在Spring中使用myBatis 12.3.1 配置SqlMapClient 12.3.2 在Spring配置myBatis ...

    Spring3.x企业应用开发实战(完整版) part1

    12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务处理 12.2.8 延迟加载的问题 12.3 在Spring中使用myBatis 12.3.1 配置SqlMapClient 12.3.2 在Spring配置myBatis ...

    Guns系统技术文档及视频

    │ │ │ ├─core----------------项目运行的核心依靠(例如aop日志记录,拦截器,监听器,guns模板引擎,shiro权限检查等) │ │ │ │ │ │ │ ├─modular----------------项目业务代码 │ │ │ │ │ │ │ ├─...

    Java学习笔记-个人整理的

    \contentsline {chapter}{Contents}{2}{section*.1} {1}Java基础}{17}{chapter.1} {1.1}基本语法}{17}{section.1.1} {1.2}数字表达方式}{17}{section.1.2} {1.3}补码}{19}{section.1.3} {1.3.1}总结}{23}{...

    Spring API

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...

Global site tag (gtag.js) - Google Analytics