我正在使用Spring 4.2.1
和Hiberante 5
,现在试图了解spring如何初始化Spring Beans定义中声明的Session,如下所示:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- properties -->
</bean>
我发现所谓的org.springframework.orm.hibernate5.LocalSessionFactoryBean实现FactoryBean<SessionFactory>
。 Taking this into account很清楚为什么我们定义SessionFactory
定义要注入类org.springframework.orm.hibernate5.LocalSessionFactoryBean
,但最终会得到SessionFactory
的实例。现在,我感到困惑的是方法getCurrentSession:
public Session getCurrentSession() throws HibernateException {
if ( currentSessionContext == null ) {
throw new HibernateException( "No CurrentSessionContext configured!" );
}
return currentSessionContext.currentSession();
}
将实际会话创建委托给SpringSessionContext,在我的情况下,它由piece of code检索:
SessionHolder sessionHolder = (SessionHolder) value;
Session session = sessionHolder.getSession();
但session
实际上是org.hibernate.internal.SessionImpl
直接基类org.hibernate.internal.AbstractSessionImpl
的实例,其本身具有属性protected transient SessionFactoryImpl factory。
因此,SessionFactory
具有CurrentSessionContext
属性,在我的情况下,SessionHolder
属性Session
依次保存实际的SessionImpl
实例。但SessionFactory
再次具有0300 : ["295", "293", "298"],
0800 : ["293", "298"],
0930 : ["295"],
1130 : ["297", "293", "298"],
1230 : ["295"]
类型的属性。
我无法理解通知。你能不能解释一下。
答案 0 :(得分:1)
嗯,CurrentSessionContext
的Spring实现不会保留SessionHolder
,而是每次调用Sessionholder
方法时都会检索currentSession
。见:
Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
...
SessionHolder sessionHolder = (SessionHolder) value;
因此,在您的情况下,会注入一些实现,但如果配置不同,则可能是另一个实现。
我认为该设计的主要目的是将关注点分开。 SessionContext
的主要目的是将事务管理器和会话持有者联系起来,根据事务配置为您提供配置良好的会话。
还有CurrentSessionContext
的其他实现,我相信hibernate至少有三个实现,所以你所描述的场景取决于注入这些类的spring配置。
正如javaDoc所述:
CurrentSessionContext实现也可以通过“hibernate.current_session_context_class”在自定义SessionFactory设置中指定