SpringSessionContext学习

简介

SpringSessionContext 是Spring框架中与Hibernate 5集成的一个类。该类实现了Hibernate的SessionContext接口,用于在Spring管理的环境中管理Hibernate的Session。

在Spring和Hibernate集成时,SpringSessionContext允许Hibernate的Session与Spring管理的应用上下文(Application Context)进行交互。通过SpringSessionContext,Hibernate的Session可以获取与Spring管理的Bean相同的生命周期,这意味着Session可以在需要时由Spring自动创建,并在不再需要时自动关闭。

SpringSessionContext的主要用途之一是支持Open Session in View模式,即在整个Web请求的生命周期内保持Hibernate的Session打开。这有助于避免懒加载异常,因为视图渲染过程中可能需要访问尚未加载的关联实体。

然而,需要注意的是,SpringSessionContext本身并不直接依赖于Spring Security。它更多地是与Spring的核心容器和事务管理功能进行交互。Spring Security是一个提供身份验证、授权等安全特性的框架,而SpringSessionContext主要关注于Hibernate Session的生命周期管理。

虽然SpringSessionContext和Spring Security可能同时在同一个Spring应用程序中使用,但它们各自服务于不同的目的,并且没有直接的依赖关系。在配置Hibernate与Spring集成时,可以使用SpringSessionContext来管理Session的生命周期,而Spring Security则用于处理与安全性相关的方面。

总结来说,org.springframework.orm.hibernate5.SpringSessionContext是Spring框架中与Hibernate 5集成的一个类,用于在Spring管理的环境中管理Hibernate的Session生命周期,但它与Spring Security没有直接的依赖关系。

源码

public class SpringSessionContext implements CurrentSessionContext {

	private final SessionFactoryImplementor sessionFactory;

	@Nullable
	private TransactionManager transactionManager;

	@Nullable
	private CurrentSessionContext jtaSessionContext;


	/**
	 * Create a new SpringSessionContext for the given Hibernate SessionFactory.
	 * @param sessionFactory the SessionFactory to provide current Sessions for
	 */
	public SpringSessionContext(SessionFactoryImplementor sessionFactory) {
		this.sessionFactory = sessionFactory;
		try {
			JtaPlatform jtaPlatform = sessionFactory.getServiceRegistry().getService(JtaPlatform.class);
			this.transactionManager = jtaPlatform.retrieveTransactionManager();
			if (this.transactionManager != null) {
				this.jtaSessionContext = new SpringJtaSessionContext(sessionFactory);
			}
		}
		catch (Exception ex) {
			LogFactory.getLog(SpringSessionContext.class).warn(
					"Could not introspect Hibernate JtaPlatform for SpringJtaSessionContext", ex);
		}
	}


	/**
	 * Retrieve the Spring-managed Session for the current thread, if any.
	 */
	@Override
	@SuppressWarnings("deprecation")
	public Session currentSession() throws HibernateException {
		//从当前事务线程中获取Session
		Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
		//如果value 是Session类型 则直接返回
		if (value instanceof Session) {
			return (Session) value;
		}
		//如果value 类型是SessionHolder
		else if (value instanceof SessionHolder) {
			// HibernateTransactionManager
			//将value 转换为SessionHolder 是Session的一个持有者或者是对Session的一中封装
			SessionHolder sessionHolder = (SessionHolder) value;
			//获取session
			Session session = sessionHolder.getSession();
			//当前session与当前事务不同步 && 当前线程有一个活动的事务同步
			if (!sessionHolder.isSynchronizedWithTransaction() &&
					TransactionSynchronizationManager.isSynchronizationActive()) {
				//则将改sessionHolder绑定到当前线程中
				TransactionSynchronizationManager.registerSynchronization(
						new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false));
				//并且设置session与当前事务同步
				sessionHolder.setSynchronizedWithTransaction(true);
				// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
				// with FlushMode.MANUAL, which needs to allow flushing within the transaction.
				//获取当前事务刷新缓存的方式
				FlushMode flushMode = SessionFactoryUtils.getFlushMode(session);
				//显示调用session.flush方法 && 并且当前事务不是只读事务
				if (flushMode.equals(FlushMode.MANUAL) &&
						!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
					//则将当前事务刷新缓存的方式设置为自动刷新
					session.setFlushMode(FlushMode.AUTO);
					//保留之前的方式
					sessionHolder.setPreviousFlushMode(flushMode);
				}
			}
			return session;
		}
		else if (value instanceof EntityManagerHolder) {
			// JpaTransactionManager
			//value 是EntityManager 则从EntityManager中获取Session
			return ((EntityManagerHolder) value).getEntityManager().unwrap(Session.class);
		}

		//使用jtaSessionContext获取session,并且将session绑定到当前事务线程中
		if (this.transactionManager != null && this.jtaSessionContext != null) {
			try {
				if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
					Session session = this.jtaSessionContext.currentSession();
					if (TransactionSynchronizationManager.isSynchronizationActive()) {
						TransactionSynchronizationManager.registerSynchronization(
								new SpringFlushSynchronization(session));
					}
					return session;
				}
			}
			catch (SystemException ex) {
				throw new HibernateException("JTA TransactionManager found but status check failed", ex);
			}
		}

		//如果上述都不符合条件 则通过sessionFactory获取session,并将其他绑定到当前线程事务中
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			Session session = this.sessionFactory.openSession();
			if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
				session.setFlushMode(FlushMode.MANUAL);
			}
			SessionHolder sessionHolder = new SessionHolder(session);
			TransactionSynchronizationManager.registerSynchronization(
					new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));
			TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
			sessionHolder.setSynchronizedWithTransaction(true);
			return session;
		}
		else {
			throw new HibernateException("Could not obtain transaction-synchronized Session for current thread");
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值