您的问题的理想答案取决于您当前使用的 Hibernate 和 Spring Framework 的版本,因为在更高版本中添加的一些新功能使得将应用程序状态注入RevisionListener 回调非常容易获得。
使用 Hibernate 5.2 或更低版本
如果您使用的是 Hibernate 5.2 或更早版本,您将受限于使用 ThreadLocal 变量注入应用程序状态的传统方法。在 Web 应用程序中,这可以通过设置 Web 过滤器或将其作为 Web 控制器的一部分轻松完成。
目标是在调用执行持久性操作的任何业务服务/bean 之前初始化ThreadLocal,并在提交持久性操作后清除状态。由于大多数基于 spring 的应用程序倾向于将服务方法包装在 @Transactional 注释中,因此在控制器中处理 ThreadLocal 的初始化和清除似乎是合乎逻辑的。
由于ThreadLocal 是一个作用于执行线程的全局变量,侦听器将能够向线程本地实例询问该值,以便在自定义修订实体上设置它。最重要的是在持久化操作开始前设置,保存后清除。
在 CDI 环境中使用 Hibernate 5.3+
这可能不适用于您,因为您处于 Spring 环境中,但为了所有可能的配置选择的完整性,我将其包括在内。
如果您在基于 CDI 的环境中使用 Hibernate 5.3 或更高版本,Hibernate 添加了对 CDI 注入的默认支持,基本上允许 Hibernate 创建的某些对象实际上成为 CDI bean 并支持将状态注入其中。换句话说
public class CustomRevisionListener implements RevisionListener {
@Inject
private UserReasonBean reasonBean;
@Override
public void newRevision(Object revisionEntity) {
// inside this method, you can get the reason from the injected reasonBean
// and now set the reason on the custom revision entity instance.
}
}
使用 Hibernate 5.3+ 但使用 Spring 5.0 或更低版本
为了让 Spring Framework bean 注入工作,您必须使用 Spring Framework 5.1 或更高版本,他们添加了该支持,否则当使用 Spring Framework 5.0 或之前的 Hibernate 时,您必须使用带有 ThreadLocal 的旧方法变量。
请参阅使用 Hibernate 5.2 或之前的版本
在 Spring 5.1+ 中使用 Hibernate 5.3+
如果您将 Hibernate 5.3 或更高版本与 Spring Framework 5.1 或更高版本一起使用,那么您很幸运。在这个用例中,您可以自动模仿默认的 CDI 支持,因为 Spring Framework 5.1 提供了自己的 bean 注册表实现并将其自动连接到 Hibernate 的框架中。简而言之,这意味着您可以轻松地将 Spring bean 自动连接到 RevisionListener,就像您使用 CDI 一样。
public class CustomRevisionListener implements RevisionListener {
@Autowired
private UserReasonBean reasonBean;
@Override
public void newRevision(Object revisionEntity) {
// inside this method, you can get the reason from the injected reasonBean
// and now set the reason on the custom revision entity instance.
}
}