`
u013830484
  • 浏览: 4593 次
社区版块
存档分类
最新评论

Hibernate源码分析2

阅读更多
再扯二句蛋:距离上一次写博客已经过了将近半个月了,因为公司的活比较多,一直没有时间研究(实际上一直都有很多活),元旦还出去浪了一圈,这个周末再来写一点`
上回大致把hibernate的启动加载配置的过程说了一遍,说到了XClass和保存的集合MetadataSourceQueue,这两个东西我暂时不想说(其实没有研究明白,怕说不好),我觉得研究hibernate框架可以从两头开始,一个是入口,也就是上一篇的启动加载过程,一个是出口,也就是我们经常调用的接口方法和类,今天从出口来讲一下,以后再将两头串起来。。。

我们常使用的接口要算是SessionFactory 了:
SessionFactory factory = cfg.buildSessionFactory();
buildSessionFactory中实际上返回的对象是SessionFactoryImpl,而SessionFactoryImpl实现了SessionFactoryImplementor接口,而SessionFactoryImplementor这个接口又继承了SessionFactory这个接口,SessionFactoryImpl实际上就是一个SessionFactory,为何需要在他们中间横插一个SessionFactoryImplementor?研究!

实际上这个不带参数的buildSessionFactory()最终调用的是带参的buildSessionFactory(ServiceRegistry serviceRegistry),这个方法返回了最终的SessionFactoryImp:
new SessionFactoryImpl(
    this,
    mapping,
    serviceRegistry,
    settings,
    sessionFactoryObserver
   );

接着往下走,话说SessionFactory的getCurrentSession方法将返回我们最终使用的Session,且看SessionFactory中的getCurrentSession方法做了什么,上源码:
if ( currentSessionContext == null ) {
   throw new HibernateException( "No CurrentSessionContext configured!" );
  }
  return currentSessionContext.currentSession();
显然是用了currentSessionContext.currentSession() 这个东西来获得的,其实 SeesionFactory本身并没有Session,而是用的是currentSessionContext 的Session!那么currentSessionContext 是啥?就是CurrentSessionContext类,从名字上就知道意思了:当前Session上下文,做了这么久的代码,上下文的意思应该知道吧
好了,再看看currentSessionContext 到底是何方神圣:currentSessionContext = buildCurrentSessionContext();
buildCurrentSessionContext这个方法做了啥?上源码:
private CurrentSessionContext buildCurrentSessionContext() {
  String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
  // for backward-compatibility
  if ( impl == null ) {
   if ( canAccessTransactionManager() ) {
    impl = "jta";
   }
   else {
    return null;
   }
  }
  if ( "jta".equals( impl ) ) {
   if ( ! transactionFactory().compatibleWithJtaSynchronization() ) {
    LOG.autoFlushWillNotWork();
   }
   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 = serviceRegistry.getService( ClassLoaderService.class ).classForName( impl );
    return ( CurrentSessionContext ) implClass
      .getConstructor( new Class[] { SessionFactoryImplementor.class } )
      .newInstance( this );
   }
   catch( Throwable t ) {
    LOG.unableToConstructCurrentSessionContext( impl, t );
    return null;
   }
  }
}
看到没有: String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );回去试着去获取我们配置的信息
(题外话,配置的获取
  this.properties = new Properties();
  this.properties.putAll( cfg.getProperties() );

Environment.CURRENT_SESSION_CONTEXT_CLASS是 :public static final String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";(在AvailableSettings中)
题外话:Environment implements AvailableSettings用来表示各种配置常量,这里的Environment 是hibernate自己的类,不是org.omg.CORBA.Environment !
看,如果我们再配置文件中将hibernate.current_session_context_class配置成thread就是返回的是ThreadLocalSessionContext(线程绑定的上下文),如果我们啥都不配的话,默认就是JTASessionContext(JTA的上下文),至于线程和JTA的含义,就属于另外讨论的话题了,有时间再研究
ok,假设我们就啥都没有配吧,就用的是JTASessionContext吧,顺着这个线走下去吧(解决主要矛盾嘛),那么肯定要来看看JTASessionContext的源码咯!首先我们很快就会发现各个SessionContext都会继承自一个抽象类:AbstractCurrentSessionContext,而AbstractCurrentSessionContext则是AbstractCurrentSessionContext implements CurrentSessionContext,
然后当然首要的是currentSession方法了,上源码:
@Override
public Session currentSession() throws HibernateException {
  final JtaPlatform jtaPlatform = factory().getServiceRegistry().getService( JtaPlatform.class );
  final TransactionManager transactionManager = jtaPlatform.retrieveTransactionManager();
  if ( transactionManager == null ) {
   throw new HibernateException( "No TransactionManagerLookup specified" );
  }
  Transaction txn;
  try {
   txn = transactionManager.getTransaction();
   if ( txn == null ) {
    throw new HibernateException( "Unable to locate current JTA transaction" );
   }
   if ( !JtaStatusHelper.isActive( txn.getStatus() ) ) {
    // We could register the session against the transaction even though it is
    // not started, but we'd have no guarantee of ever getting the map
    // entries cleaned up (aside from spawning threads).
    throw new HibernateException( "Current transaction is not in progress" );
   }
  }
  catch ( HibernateException e ) {
   throw e;
  }
  catch ( Throwable t ) {
   throw new HibernateException( "Problem locating/validating JTA transaction", t );
  }
  final Object txnIdentifier = jtaPlatform.getTransactionIdentifier( txn );
  Session currentSession = ( Session ) currentSessionMap.get( txnIdentifier );
  if ( currentSession == null ) {
   currentSession = buildOrObtainSession();
   try {
    txn.registerSynchronization( buildCleanupSynch( txnIdentifier ) );
   }
   catch ( Throwable t ) {
    try {
     currentSession.close();
    }
    catch ( Throwable ignore ) {
     LOG.debug( "Unable to release generated current-session on failed synch registration", ignore );
    }
    throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" );
   }
   currentSessionMap.put( txnIdentifier, currentSession );
  }
  else {
   validateExistingSession( currentSession );
  }
  return currentSession;
}

其中,factory()是父类(AbstractCurrentSessionContext )的方法,只是:
public SessionFactoryImplementor factory() {
  return factory;
}
factory而已,这个factory是啥??
还记得SessionFactoryImp中buildCurrentSessionContext方法的return new JTASessionContext( this );吗?这个factory就是this(SessionFactoryImp实例)
final JtaPlatform jtaPlatform = factory().getServiceRegistry().getService( JtaPlatform.class );中 factory().getServiceRegistry()返回的是SessionFactoryImp的变量serviceRegistry,何处来的?
还记得我们在Configuration中new SessionFactoryImp的时候吗?
new SessionFactoryImpl(
    this,
    mapping,
    serviceRegistry,
    settings,
    sessionFactoryObserver
   )

上述的的这个不带参数的buildSessionFactory()最终调用的是带参的buildSessionFactory(ServiceRegistry serviceRegistry)的调用之前buildSessionFactory方法中做了:
final ServiceRegistry serviceRegistry =  new ServiceRegistryBuilder()
    .applySettings( properties )
    .buildServiceRegistry();
applySettings( properties )是将hibernate.properties产生的Properties对象传递给ServiceRegistryBuilder,而buildServiceRegistry方法则是发生事情的地方:
public ServiceRegistry buildServiceRegistry() {
  Map<?,?> settingsCopy = new HashMap();
  settingsCopy.putAll( settings );
  Environment.verifyProperties( settingsCopy );
  ConfigurationHelper.resolvePlaceHolders( settingsCopy );
  for ( Integrator integrator : bootstrapServiceRegistry.getService( IntegratorService.class ).getIntegrators() ) {
   if ( ServiceContributingIntegrator.class.isInstance( integrator ) ) {
    ServiceContributingIntegrator.class.cast( integrator ).prepareServices( this );
   }
  }
  return new StandardServiceRegistryImpl( bootstrapServiceRegistry, initiators, providedServices, settingsCopy );
}
这就是我们得到SessionFactory的大致过程,其中的几个细节值得研究:
1:我们只是知道了要传入ServiceRegistry ,那是做啥的?
2:SessionFactoryImplementor的意义
这次先到这里,下回就解决这些细节问题,那么入口和出口的大致流程就完事儿了```
0
4
分享到:
评论

相关推荐

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

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

    hibernate源码分析过程

    Hibernate 源码分析过程 Hibernate 是一个基于 Java 的 ORM(Object-Relation Mapping)框架,允许开发者使用面向对象的方式与关系数据库交互。在本文中,我们将对 Hibernate 的源码进行深入分析,并探讨其核心特性...

    Hibernate源码解析(一)

    - 错误排查:当遇到问题时,源码分析能更准确地定位问题所在,提高解决问题的效率。 - 自定义扩展:熟悉源码后,我们可以根据需求自定义拦截器、事件监听器等,实现特定功能。 总结来说,Hibernate源码解析是一个...

    hibernate源码分析

    **Hibernate源码分析** Hibernate,一个著名的开源Java对象关系映射(ORM)框架,通过将Java对象和数据库表之间的映射关系自动化,极大地简化了数据访问层的开发工作。本篇将深入探讨Hibernate的源码,揭示其执行...

    Hibernate源码解析(三)

    在阅读《Hibernate源码解析(三)》的过程中,配合hibernate源码分析(三).docx文档,读者可以更直观地理解这些概念,并可能涉及具体的类和方法,如`Query`、`SessionFactoryBuilder`、`EntityPersister`等。...

    Hibernate源码

    Hibernate源码分析有助于深入理解其内部机制,提高开发效率,优化数据库操作性能。 1. **Hibernate核心模块(hibernate-core)** Hibernate的核心模块包含了ORM框架的主要功能,如实体管理、查询语言(HQL)、事件...

    hibernate源码分析一_启动过程_

    **hibernate源码分析:启动过程** 在深入探讨Hibernate启动过程之前,首先需要了解Hibernate是什么。Hibernate是一个开源的对象关系映射(ORM)框架,它为Java开发人员提供了一种在Java应用程序中操作数据库的方式...

    传智播客hibernate源码

    标题"传智播客hibernate源码"暗示了这是一个关于Hibernate框架的源代码学习资源,可能包含了对Hibernate框架内部机制的深入解析,以及如何在实际项目中应用Hibernate的相关示例。 描述中的内容重复,进一步确认了这...

    hibernate源码的学习

    在Hibernate源码的学习过程中,我们可以深入理解ORM的工作原理,提高我们的Java开发技能,并且能够更好地优化数据库操作。 一、Hibernate核心组件 1. Configuration:配置对象,负责读取hibernate.cfg.xml文件,...

    Hibernate源码解析(二)

    源码分析会展示这些查询API的底层实现,以及它们如何转换为SQL语句执行。 六、第二级缓存与查询缓存 为了提高性能,Hibernate支持二级缓存和查询缓存。二级缓存可以存储已加载的实体,减少对数据库的访问;查询...

    hibernate源码

    源码分析是深入理解其工作原理的关键,特别是对于那些希望优化性能、解决特定问题或者扩展其功能的开发者来说。下面我们将详细探讨Hibernate的核心组件和工作流程。 1. **对象关系映射(ORM)**:Hibernate通过ORM...

    Struts,Spring,Hibernate源码包

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

    精通hibernate源码ch5

    《精通Hibernate源码Chapter5:Java对象持久化技术详解》 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。深入理解Hibernate的源码,不仅能帮助开发者提高工作效率,还能...

    hibernate源码包

    **hibernate源码分析** Hibernate 是一个开源的Java库,它为对象关系映射(ORM)提供了强大的支持。在Java编程中,ORM允许开发者使用面向对象的方式来操作数据库,而无需编写大量的SQL语句,从而提高了开发效率和...

    传智播客李勇hibernate源码1-20课

    传智播客李勇hibernate源码1-20课,目录如下:01_hibernate介绍与动手入门体验;02_hibernate入门案例的细节分析; 03_hibernate入门案例的代码优化; 04_Session接口及get|load|persist方法 05_实体对象的三种状态...

    精通Hibernate源码

    了解Hibernate的基本架构,包括SessionFactory、Session、Transaction等核心组件,是深入源码分析的基础。 2. **Entity和Mapping**:在Hibernate中,实体(Entity)是Java对象,代表数据库中的记录。XML或注解方式...

    Spring,Hibernate整合源码

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

Global site tag (gtag.js) - Google Analytics