在(Spring MVC)Web 请求中应该如何处理 SessionFactory 实例?
Posted
技术标签:
【中文标题】在(Spring MVC)Web 请求中应该如何处理 SessionFactory 实例?【英文标题】:How should SessionFactory instances be handled within (Spring MVC) web requests? 【发布时间】:2018-01-20 10:39:03 【问题描述】:这是一个非常基本的问题,但我需要帮助。假设我们在 spring 中创建了一个单例 bean,那么 spring ioc 将创建该特定 bean 的单个实例,并且当某种代码需要它时,它会被注入。这很好。但我对多线程环境如何管理它感到困惑。就像我们在 spring 中将 sesssionFactory bean 作为单例一样,然后向需要 sessionFactory bean 的特定 rest url 发出许多请求。 Spring 框架如何为这么多请求提供单个 bean 实例。
【问题讨论】:
【参考方案1】:您是在谈论持久性提供程序会话工厂,例如Hibernate SessionFactory?
这个工厂应该为每个 DataSource 存在一次,因为创建它并不便宜(连接处理、内存消耗),并且绝对应该在整个应用程序生命周期内重用,所以此时单例是要走的路。工厂是不可变的(线程安全的),不会有并发问题。
每个传入线程(由网络请求创建)都应该重用这个工厂来创建它自己的会话,并且这个会话应该用于这个线程,无论它被访问的频率如何(例如存储在线程局部变量中)。
例如如果我们现在在抽象层中向上移动到 JPA 级别,JPA EntityManagerFactory 正在包装 Hibernate SessionFactory,如果你想使用 JPA 挂件到 Hibernate Session - EntityManager - 你想让 Spring 管理它,你会得到一个像这样的 EntityManager 代理:
@PersistenceContext
private EntityManager entityManager;
这将为您的业务代码提供当前线程的 EntityManager 代理(包装的 Session)。
如果您使用Spring Data JPA、它的存储库和@Transactional
方法,这同样适用于下一级抽象。在这种情况下,Spring 也会为您处理。
【讨论】:
谢谢你..你解释得很好。现在我了解了 SessionFactory 如何用作单例 bean。但是我也想知道,并发Web请求时,如何使用单例bean(由@Component注解生成)? 如果是单例(默认)当然是所有线程共享的。如果它是您自己的 Bean 并且它具有状态(成员),则您必须关心线程安全/不变性。否则,您可能会遇到副作用/并发问题。 如果我经常使用一个类,并且这个类有一些局部变量。我可以将它声明为一个 bean 并将其自动装配到我需要它的每个类而不关心并发问题吗? 如果你的bean的方法只使用局部变量,是的。如果类有成员,则没有,因为成员在线程之间共享。这是一个通用的(Java)并发事情,如何创建单例并不重要,与 Spring / DI 无关。也许尝试在这里开始获取更多信息:docs.oracle.com/javase/tutorial/essential/concurrency以上是关于在(Spring MVC)Web 请求中应该如何处理 SessionFactory 实例?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Spring MVC中基于http请求头启用json的动态漂亮打印?
Spring Web MVC:对请求参数和路径变量使用相同的请求映射