Hibernate 提供了多种 拦截器(Interceptor) 和 事件监听机制(Event Listener),用于在实体生命周期的各个阶段插入自定义逻辑,例如审计日志、数据校验、自动填充字段等。以下是详细说明:
一、拦截器(Interceptor)
Hibernate 的 Interceptor
接口提供了一种 集中式的回调机制,开发者可以通过实现这个接口来拦截和处理实体的 CRUD 操作。
1. 常用方法
方法 | 说明 |
---|---|
onSave(Object entity, ...) | 实体保存前触发(INSERT) |
onFlushDirty(Object entity, ...) | 实体更新前触发(UPDATE) |
onDelete(Object entity, ...) | 实体删除前触发(DELETE) |
onLoad(Object entity, ...) | 实体加载后触发(SELECT) |
preFlush(Collection entities) | flush 开始前触发 |
postFlush(Collection entities) | flush 结束后触发 |
2. 用途示例
- 自动设置创建时间、更新时间字段
- 对敏感操作记录审计日志
- 在删除前做检查或软删除处理
- 动态数据过滤(例如:多租户)
二、事件监听机制(Event Listener)
相比 Interceptor,事件监听机制更细粒度,更具扩展性,基于 Hibernate 的 org.hibernate.event.spi
包下的事件体系。
1. 常见事件类型(按生命周期分类)
事件接口 | 说明 |
---|---|
PreInsertEventListener | 插入前触发 |
PostInsertEventListener | 插入后触发 |
PreUpdateEventListener | 更新前触发 |
PostUpdateEventListener | 更新后触发 |
PreDeleteEventListener | 删除前触发 |
PostDeleteEventListener | 删除后触发 |
LoadEventListener | 加载时触发 |
FlushEventListener | flush 事件触发 |
2. 使用方式
- 实现对应的接口,例如:
public class AuditListener implements PreUpdateEventListener {
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
Object entity = event.getEntity();
if (entity instanceof Auditable) {
((Auditable) entity).setLastModified(new Date());
}
return false; // 返回 true 会阻止默认更新
}
}
- 注册监听器:
- 使用 Hibernate
Configuration
配置类手动注册 - 或在 Spring Boot 中使用
LocalSessionFactoryBean
进行集成
- 使用 Hibernate
三、两者对比
对比项 | Interceptor | EventListener |
---|---|---|
粒度 | 粗 | 细(支持每个操作前后) |
灵活性 | 一般 | 更强 |
推荐使用场景 | 快速统一处理逻辑 | 复杂、多类型事件监听 |
配置方式 | sessionFactory 设置一个 | 可注册多个不同监听器 |
四、实际应用场景示例
- 审计日志记录:监听
PostInsertEvent
和PostUpdateEvent
- 字段自动赋值:如
createdAt
,updatedAt
使用PreInsertEventListener
等 - 数据过滤:例如基于租户 ID 过滤数据
- 操作权限验证:在
PreDeleteEvent
判断是否允许删除
如果你在使用 Spring + Hibernate,建议优先使用 事件监听机制 配合 AOP 或注解来管理更清晰的业务逻辑。需要简单处理时,可直接用 Interceptor
。