Hibernate源码分析:入门代码流程
跳到导航
跳到搜索
关于
对于入门的代码案例,分析其执行流程,有助于理解其设计并熟悉 API 的使用。
入门代码:
class HibernateTest{ @Test public void testDemo() { // 加载 hibernate 核心配置文件 Configuration cfg = new Configuration(); cfg.configure(); // 根据 hibernate 核心配置文件内容,创建 sessionFactory SessionFactory sessionFactory = cfg.buildSessionFactory(); // 使用 SessionFactory 创建 session 对象 Session session = sessionFactory.openSession(); // Session session = sessionFactory.grtCurrentSession(); // 使用事务 Transaction tx = null; try{ // 开启事务 tx = session.beginTransaction(); // 逻辑代码 User user = new User(); user.setUsername("Eijux"); user.setPassword("123456"); user.setAddress("成都"); session.save(user); // 提交事务 tx.commit(); }catch(HibernateException e){ if(tx != null){ // 回滚事务 tx.rollback(); } throw e; }finally{ if(session != null){ // 关闭 session session.close(); } } // 关闭 sessionFactory sessionFactory.close(); } }
加载核心配置文件
对于:
Configuration cfg = new Configuration(); cfg.configure();
其过程如下:
- 创建一个 Configuration 对象;
- 调用其 configure() 方法:
public class Configuration { ... public Configuration() { this( new BootstrapServiceRegistryBuilder().build() ); } public Configuration(BootstrapServiceRegistry serviceRegistry) { this.bootstrapServiceRegistry = serviceRegistry; this.metadataSources = new MetadataSources( serviceRegistry ); reset(); } public Configuration(MetadataSources metadataSources) { this.bootstrapServiceRegistry = getBootstrapRegistry( metadataSources.getServiceRegistry() ); this.metadataSources = metadataSources; reset(); } ... }
- 有多个重载的构造方法,用于不同加载方式。
- 其实默认的无参构造函数,将创建一个 BootstrapServiceRegistryImpl 类(继承了 BootstrapServiceRegistryBuilder 类)的对象。
【未完待续……】
创建 sessionFactory
对于:
SessionFactory sessionFactory = cfg.buildSessionFactory();
其过程如下:
- 调用 Configuration 对象的 buildSessionFactory() 方法;
- 调用其 configure() 方法:
public class Configuration { ... public SessionFactory buildSessionFactory() throws HibernateException { log.debug( "Building session factory using internal StandardServiceRegistryBuilder" ); standardServiceRegistryBuilder.applySettings( properties ); return buildSessionFactory( standardServiceRegistryBuilder.build() ); } ... public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException { log.debug( "Building session factory using provided StandardServiceRegistry" ); /* MetadataSources 类的 getMetadataBuilder(), * 将返回一个【MetadataBuilderImpl】类的对象 * * MetadataBuilderImpl:实现了 MetadataBuilderImplementor 接口(继承自 MetadataBuilder 等接口) */ final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder( (StandardServiceRegistry) serviceRegistry ); ... /* 其实就是调用 MetadataBuilderImpl 的 bulid(), * 最终会返回一个【MetadataImpl】对象 * * MetadataImpl:实现了 MetadataImplementor 接口(继承自 Metadata 等接口) */ final Metadata metadata = metadataBuilder.build(); /* 其实就是调用 MetadataImpl 的 getSessionFactoryBuilder(), * 将返回一个【SessionFactoryBuilderImpl】对象 * * SessionFactoryBuilderImpl:实现了 SessionFactoryBuilderImplementor 接口(继承自 SessionFactoryBuilder 等接口) */ final SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder(); ... /* 其实就是调用 SessionFactoryBuilderImpl 的 build(), * 将返回一个【SessionFactoryImpl】对象 * * SessionFactoryImpl:实现了 SessionFactoryImplementor 接口(继承自 SessionFactory 等接口) */ return sessionFactoryBuilder.build(); } ... }
- MetadataSources 类:元数据信息源(映射 XML、注释)的入口点。(元数据信息源)
- 用于告诉 Hibernate 有关源的信息,然后调用 buildMetadata(),或使用 getMetadataBuilder() 自定义源的处理方式(命名策略等);
- MetadataBuilderImpl 类:元数据构造器。
- MetadataImpl 类:绑定元模型期间收集的配置数据的容器。(元数据信息)
- SessionFactoryBuilderImpl 类:SessionFactory 构造器。
- SessionFactoryImpl 类:SessionFactory 接口的具体实现。
最终返回的是 SessionFactoryImpl 类(间接实现了 SessionFactory 接口)的对象。
创建 session
openSession()
对于:
Session session = sessionFactory.openSession();
其实就是调用 SessionFactoryImpl 类的 openSession():
public class SessionFactoryImpl implements SessionFactoryImplementor { ... public SessionFactoryImpl(final MetadataImplementor metadata, SessionFactoryOptions options) { LOG.debug( "Building session factory" ); ... try { ... LOG.debug( "Instantiated session factory" ); ... this.defaultSessionOpenOptions = withOptions(); ... SessionFactoryRegistry.INSTANCE.addSessionFactory( getUuid(), name, settings.isSessionFactoryNameAlsoJndiName(), this, serviceRegistry.getService( JndiService.class ) ); } catch (Exception e) { for ( Integrator integrator : serviceRegistry.getService( IntegratorService.class ).getIntegrators() ) { integrator.disintegrate( this, serviceRegistry ); integratorObserver.integrators.remove( integrator ); } close(); throw e; } } ... // openSession() public Session openSession() throws HibernateException { final CurrentTenantIdentifierResolver currentTenantIdentifierResolver = getCurrentTenantIdentifierResolver(); //We can only use reuse the defaultSessionOpenOptions as a constant when there is no TenantIdentifierResolver if ( currentTenantIdentifierResolver != null ) { return this.withOptions().openSession(); } else { return this.defaultSessionOpenOptions.openSession(); } } ... public SessionBuilderImplementor withOptions() { // 返回 SessionBuilderImpl 类(内部类)的对象 return new SessionBuilderImpl( this ); } ... // 内部类 SessionBuilderImpl public static class SessionBuilderImpl<T extends SessionBuilder> implements SessionBuilderImplementor<T>, SessionCreationOptions { ... /* 返回一个 SessionImpl 对象 * * SessionImpl:实现了 SessionImplementor 接口(继承自 Session 等接口) */ public Session openSession() { log.tracef( "Opening Hibernate Session. tenant=%s", tenantIdentifier ); return new SessionImpl( sessionFactory, this ); } ... } ... }
最终返回的是 SessionImpl 类(间接实现了 Session 接口)的对象。
getCurrentSession()
对于:
Session session = sessionFactory.getCurrentSession();
其实就是调用 SessionFactoryImpl 类的 getCurrentSession():
- 创建一个 Configuration 对象;
- 调用其 configure() 方法:
public class SessionFactoryImpl implements SessionFactoryImplementor { ... public SessionFactoryImpl(final MetadataImplementor metadata, SessionFactoryOptions options) { LOG.debug( "Building session factory" ); ... try { ... LOG.debug( "Instantiated session factory" ); ... currentSessionContext = buildCurrentSessionContext(); ... SessionFactoryRegistry.INSTANCE.addSessionFactory( getUuid(), name, settings.isSessionFactoryNameAlsoJndiName(), this, serviceRegistry.getService( JndiService.class ) ); } catch (Exception e) { ... } } ... // getCurrentSession() public Session getCurrentSession() throws HibernateException { if ( currentSessionContext == null ) { throw new HibernateException( "No CurrentSessionContext configured!" ); } return currentSessionContext.currentSession(); } ... // 根据不同的“current_session_context_class”,创建不同的 SessionContext 对象 private CurrentSessionContext buildCurrentSessionContext() { String impl = (String) properties.get( 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; } } } ... }
“current_session_context_class”配置,见:Hibernate笔记 2:配置文件详解#配置:事务管理