`
周英能
  • 浏览: 187970 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

spring、hibernate源码分析二

 
阅读更多

从上篇文章分析得出,hibernate初始化时,flushBeforeCompletion、autoCloseSession默认为false

releaseMode为auto。还有hibernate.jdbc.batch_size默认为0等。那现在来分析openSession和getCurrentSession的区别就不难了。

    首先进入sessionFactory的实现类SessionFactoryImpl,接到上篇文章继续分析:

上篇文章的configuration最后调用代码如下:

 

return new SessionFactoryImpl(
				this,
				mapping,
				settings,
				getInitializedEventListeners(),
				sessionFactoryObserver
			);

 

public SessionFactoryImpl(
			Configuration cfg,
	        Mapping mapping,
	        Settings settings,
	        EventListeners listeners,
			SessionFactoryObserver observer) throws HibernateException {
                //省略
		currentSessionContext = buildCurrentSessionContext();
               //省略
	}

private CurrentSessionContext buildCurrentSessionContext() {
String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
		// for backward-compatability
		if ( impl == null && transactionManager != null ) {
			impl = "jta";
		}

		if ( impl == null ) {
			return null;
		}
		else if ( "jta".equals( impl ) ) {
			if ( settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions() ) {
				log.warn( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
			}
			return new JTASessionContext( this );
		}
		else if ( "thread".equals( impl ) ) {
			return new ThreadLocalSessionContext( this );
		}
		else if ( "managed".equals( impl ) ) {
			return new ManagedSessionContext( this );
		}
		else {
			try {
				Class implClass = ReflectHelper.classForName( impl );
				return ( CurrentSessionContext ) implClass
						.getConstructor( new Class[] { SessionFactoryImplementor.class } )
						.newInstance( new Object[] { this } );
			}
			catch( Throwable t ) {
				log.error( "Unable to construct current session context [" + impl + "]", t );
				return null;
			}
		}
	}

 

 默认会采用jta事物

那么现在调用openSession继续追踪

 

public org.hibernate.classic.Session openSession() throws HibernateException {
		return openSession(interceptor);
	}


public org.hibernate.classic.Session openSession(Interceptor sessionLocalInterceptor)throws HibernateException 
{
long timestamp = settings.getRegionFactory().nextTimestamp();
return openSession( null, true, timestamp, sessionLocalInterceptor );
}

private SessionImpl openSession(
		Connection connection,
	    boolean autoClose,
	    long timestamp,
	    Interceptor sessionLocalInterceptor
	) {
		return new SessionImpl(
		        connection,
		        this,
		        autoClose,
		        timestamp,
		        sessionLocalInterceptor == null ? interceptor : sessionLocalInterceptor,
		        settings.getDefaultEntityMode(),
		        settings.isFlushBeforeCompletionEnabled(),
		        settings.isAutoCloseSessionEnabled(),
		        settings.getConnectionReleaseMode()
			);
	}

 

 发现通过openSession开启的Session有以下状态:flushBeforeCompletionEnabled=false,autoCloseSessionEnabled=false,connectionReleaseMode=true

调用getCurrentSession进行追踪:

 

public org.hibernate.classic.Session getCurrentSession() throws HibernateException {
		if ( currentSessionContext == null ) {
			throw new HibernateException( "No CurrentSessionContext configured!" );
		}
		return currentSessionContext.currentSession();
}

 

 进入ThreadLocalSessionContext继续追踪

 

public final Session currentSession() throws HibernateException {
		Session current = existingSession( factory );
		if (current == null) {
			current = buildOrObtainSession();
			// register a cleanup synch
			current.getTransaction().registerSynchronization( buildCleanupSynch() );
			// wrap the session in the transaction-protection proxy
			if ( needsWrapping( current ) ) {
				current = wrap( current );
			}
			// then bind it
			doBind( current, factory );
		}
		return current;
	}

 

protected Session buildOrObtainSession() {
return factory.openSession(
				null,
		        isAutoFlushEnabled(),
		        isAutoCloseEnabled(),
		        getConnectionReleaseMode()
			);
}

protected boolean isAutoFlushEnabled() {
		return true;
}

protected boolean isAutoCloseEnabled() {
		return true;
	}

 可看出getCurrentSession的状态

flushBeforeCompletionEnabled=true,autoCloseSessionEnabled=true,connectionReleaseMode=true

现在两种方式都是最终调用同一个方法,继续跟踪

 

public org.hibernate.classic.Session openSession(
			final Connection connection,
	        final boolean flushBeforeCompletionEnabled,
	        final boolean autoCloseSessionEnabled,
	        final ConnectionReleaseMode connectionReleaseMode) throws HibernateException {
		return new SessionImpl(
				connection,
		        this,
		        true,
		        settings.getRegionFactory().nextTimestamp(),
		        interceptor,
		        settings.getDefaultEntityMode(),
		        flushBeforeCompletionEnabled,
		        autoCloseSessionEnabled,
		        connectionReleaseMode
			);
	}
SessionImpl(
			final Connection connection,
			final SessionFactoryImpl factory,
			final boolean autoclose,
			final long timestamp,
			final Interceptor interceptor,
			final EntityMode entityMode,
			final boolean flushBeforeCompletionEnabled,
			final boolean autoCloseSessionEnabled,
			final ConnectionReleaseMode connectionReleaseMode) {
		super( factory );
		this.rootSession = null;
		this.timestamp = timestamp;
		this.entityMode = entityMode;
		this.interceptor = interceptor;
		this.listeners = factory.getEventListeners();
		this.actionQueue = new ActionQueue( this );
		this.persistenceContext = new StatefulPersistenceContext( this );
		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
		this.connectionReleaseMode = connectionReleaseMode;
		this.jdbcContext = new JDBCContext( this, connection, interceptor );

		loadQueryInfluencers = new LoadQueryInfluencers( factory );

		if ( factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatisticsImplementor().openSession();
		}

		if ( log.isDebugEnabled() ) {
			log.debug( "opened session at timestamp: " + timestamp );
		}
	}

继续跟踪this.jdbcContext = new JDBCContext( this, connection, interceptor );session和collection的关联过程

 

public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
		this.owner = owner;
		this.connectionManager = new ConnectionManager(
		        owner.getFactory(),
		        this,
		        owner.getConnectionReleaseMode(),
		        connection,
		        interceptor
			);

		final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
		        || owner.isFlushBeforeCompletionEnabled()
		        || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
		if ( registerSynchronization ) {
			registerSynchronizationIfPossible();
		}
}

 继续跟踪ConnectionManager的创建过程

 

public ConnectionManager(
	        SessionFactoryImplementor factory,
	        Callback callback,
	        ConnectionReleaseMode releaseMode,
	        Connection connection,
	        Interceptor interceptor) {
		this.factory = factory;
		this.callback = callback;

		this.interceptor = interceptor;
		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );

		this.connection = connection;
		wasConnectionSupplied = ( connection != null );

		this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
	}
public Connection getConnection() throws HibernateException {
		if ( isClosed ) {
			throw new HibernateException( "connection manager has been closed" );
		}
		if ( connection == null  ) {
			openConnection();
		}
		return connection;
	}
private void openConnection() throws HibernateException {
		if ( connection != null ) {
			return;
		}

		log.debug("opening JDBC connection");
		try {
			connection = factory.getConnectionProvider().getConnection();
		}
		catch (SQLException sqle) {
			throw JDBCExceptionHelper.convert(
					factory.getSQLExceptionConverter(),
					sqle,
					"Cannot open connection"
				);
		}

		callback.connectionOpened(); // register synch; stats.connect()
	}

分享到:
评论

相关推荐

    Spring5 源码分析(第 2 版) .zip

    《Spring5 源码分析(第 2 版)》是针对Spring框架第五个主要版本的深度解析著作,由知名讲师倾心打造,旨在帮助读者深入理解Spring框架的内部工作机制,提升对Java企业级应用开发的专业技能。本书涵盖了Spring框架的...

    struts2 spring hibernate框架技术与项目实战 光盘源码上

    在本资源中,"struts2 spring hibernate框架技术与项目实战 光盘源码 上"提供了这三大框架的实践项目代码,帮助开发者深入理解并掌握它们的集成与应用。 Struts2作为MVC(模型-视图-控制器)框架,主要负责处理HTTP...

    Spring,Hibernate整合源码

    源码分析通常涉及对配置文件的理解,如Spring的beans.xml和Hibernate的hibernate.cfg.xml,以及相关类的设计和交互。此外,还可以通过源码学习到如何处理异常、优化数据库操作,以及如何设计符合松耦合原则的架构。

    spring源码分析(1-10)

    Spring 源代码分析系列涵盖了多个关键模块,包括事务处理、IoC容器、JDBC、MVC、AOP以及与Hibernate和Acegi安全框架的集成。以下是对这些知识点的详细阐述: 1. **Spring 事务处理**:Spring 提供了声明式事务管理...

    struts2 spring hibernate框架技术与项目实战 光盘源码 中

    源码分析: 光盘源码中可能包含了实现SSH架构的示例项目,包括Action类(Struts2)、Service接口及实现类(Spring)、DAO接口及实现类(Hibernate)、配置文件(如struts.xml、spring-context.xml、hibernate.cfg....

    Struts,Spring,Hibernate源码包

    源码分析对于开发者来说,是提升技术水平和深入理解框架原理的关键步骤。 **Struts** 是一个基于MVC(Model-View-Controller)设计模式的Java Web框架,主要负责处理用户请求和控制业务流程。它的核心是Action...

    spring,hibernate源码

    Spring 和 Hibernate 是两...总之,Spring和Hibernate的源码分析是一次深入Java企业级开发的宝贵旅程,对于提升开发者的技术能力具有极大的帮助。通过学习源码,可以更好地利用这两个框架,提高项目开发的效率和质量。

    hibernate源码分析一[启动过程]

    标题:hibernate源码分析一[启动过程] 在深入探讨Hibernate框架的启动过程之前,我们首先需要了解几个核心的概念和类,它们是Hibernate启动流程的基石。 ### 1. 关键类与接口 #### Environment类 `Environment`类...

    Struts2 Spring Hibernate的配置及登录实例(附源码)

    6. **源码分析** - 源码中可能包含`struts.xml`、`applicationContext.xml`、`hibernate.cfg.xml`等配置文件。 - LoginAction类实现登录功能,可能包含validate()方法进行验证,execute()方法处理登录逻辑。 - ...

    会员管理系统jar源码下载(struts+hibernate+spring).zip

    这是一个基于Java技术栈的会员管理系统源码,使用了经典的SSH框架——Struts、Hibernate和Spring。这个系统的主要目的是实现对会员信息的有效管理和操作,通过这三个框架的集成,实现了业务层、持久层和表现层的解耦...

    Spring4+SpringMVC4+Hibernate4整合源码

    5. **源码分析**:对于"Spring4+SpringMVC4+Hibernate4整合源码",研究这些源码可以帮助开发者深入理解三大框架的内部工作原理,学习如何配置和使用它们进行实际项目开发。通过源码,你可以看到如何配置Spring的...

    struts+hibernate+spring源码

    **Struts框架源码分析:** Struts是一个基于MVC设计模式的Java Web框架,它的核心是ActionServlet,它负责接收请求并转发到相应的Action。源码中可以看到ActionMapping、ActionForm、ActionForward等关键组件,这些...

    spring hibernate 事务管理学习笔记(一)

    对于源码分析,Spring的`TransactionInterceptor`拦截器在方法调用前后进行事务的开启和提交/回滚。当发生异常时,Spring会根据回滚规则判断是否需要回滚事务。在实际开发中,理解这部分源码有助于我们更深入地掌握...

    java spring hibernate struts2源码

    源码分析可以帮助我们理解这些框架的工作原理,从而更好地运用它们,解决开发过程中的问题。通过阅读和学习这些源码,开发者可以提升自己的技术水平,理解设计模式,掌握如何构建大型、可扩展的应用系统。 总的来说...

    spring+hibernate学习笔记和项目源代码

    2. **Hibernate ORM**: Hibernate是一个对象关系映射(ORM)框架,它消除了Java应用程序与数据库之间的繁琐交互。通过将Java类与数据库表进行映射,开发者可以使用面向对象的方式来操作数据,而无需关心底层SQL...

    spring5源码分析笔记

    Spring5源码分析笔记旨在深入理解Spring的工作原理,帮助开发者提升技能,优化代码,以及更好地利用其核心特性。以下是对Spring5源码的一些关键知识点的详细解释: 1. **依赖注入(Dependency Injection,DI)**:...

    struts2 hibernate spring 整合批量删除源码

    Struts2、Hibernate和Spring是Java Web开发中的三大框架,它们各自负责不同的职责,而将它们整合在一起可以构建出高效、灵活的企业级应用。在这个批量删除的源码中,我们可以看到这三个框架协同工作的实例。 首先,...

    hibernate和Spring源码

    Spring源码分析主要关注以下内容: 1. **依赖注入(DI)**:Spring通过XML配置或注解实现对象间的依赖关系,解耦组件,提高代码可测试性。 2. **面向切面编程(AOP)**:AOP允许开发者定义“横切关注点”,如日志...

    三大框架源码:spring+hibernate+struts2

    在IT领域,Spring、Hibernate和Struts2被誉为Java Web开发中的“三大框架”。这三大框架在构建企业级应用中起着至关重要的作用,它们分别解决了应用程序的依赖管理、持久化和MVC(Model-View-Controller)架构问题。...

    spring高级源码分析

    《Spring高级源码分析》是针对Java开发人员深入理解Spring框架的一份宝贵资源。Spring作为Java企业级应用的基石,其强大的功能和灵活性源于其深厚的设计理念和精巧的源码实现。本分析将深入探讨Spring的核心机制,...

Global site tag (gtag.js) - Google Analytics