“Hibernate源码分析:入门代码流程”的版本间差异
跳到导航
跳到搜索
(创建页面,内容为“category:Hibernate == 关于 == 对于入门的代码案例,分析其执行流程,有助于理解其设计并熟悉 API 的使用。 入门代码: : <syntaxhighlight lang="Java" highlight=""> class HibernateTest{ @Test public void testDemo() { // 加载 hibernate 核心配置文件 Configuration cfg = new Configuration(); cfg.configure(); // 根据 hibernate 核心配置文件内容,创建 sessionFactory SessionFactory sessionFacto…”) |
|||
(未显示同一用户的5个中间版本) | |||
第59行: | 第59行: | ||
== 加载核心配置文件 == | == 加载核心配置文件 == | ||
对于: | |||
: <syntaxhighlight lang="Java" highlight=""> | |||
Configuration cfg = new Configuration(); | |||
cfg.configure(); | |||
</syntaxhighlight> | |||
其过程如下: | |||
# 创建一个 Configuration 对象; | |||
# 调用其 configure() 方法: | |||
#: <syntaxhighlight lang="Java" highlight=""> | |||
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(); | |||
} | |||
... | |||
} | |||
</syntaxhighlight> | |||
#* 有多个重载的构造方法,用于不同加载方式。 | |||
#* 其实默认的无参构造函数,将创建一个 BootstrapServiceRegistryImpl 类(继承了 BootstrapServiceRegistryBuilder 类)的对象。 | |||
【未完待续……】 | |||
== 创建 sessionFactory == | == 创建 sessionFactory == | ||
对于: | |||
: <syntaxhighlight lang="Java" highlight=""> | |||
SessionFactory sessionFactory = cfg.buildSessionFactory(); | |||
</syntaxhighlight> | |||
其过程如下: | |||
# 调用 Configuration 对象的 buildSessionFactory() 方法; | |||
# 调用其 configure() 方法: | |||
#: <syntaxhighlight lang="Java" highlight=""> | |||
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(); | |||
} | |||
... | |||
} | |||
</syntaxhighlight> | |||
#* MetadataSources 类:'''元数据信息源(映射 XML、注释)'''的入口点。(元数据信息源) | |||
#** 用于告诉 Hibernate 有关源的信息,然后调用 buildMetadata(),或使用 getMetadataBuilder() 自定义源的处理方式(命名策略等); | |||
#* MetadataBuilderImpl 类:元数据构造器。 | |||
#* MetadataImpl 类:绑定元模型期间收集的配置数据的容器。(元数据信息) | |||
#* SessionFactoryBuilderImpl 类:SessionFactory 构造器。 | |||
#* '''SessionFactoryImpl''' 类:SessionFactory 接口的具体实现。 | |||
最终返回的是 <span style="color: blue; font-size: 150%;">'''SessionFactoryImpl'''</span> 类(间接实现了 SessionFactory 接口)的对象。 | |||
== 创建 session == | == 创建 session == | ||
=== openSession() === | |||
对于: | |||
: <syntaxhighlight lang="Java" highlight=""> | |||
Session session = sessionFactory.openSession(); | |||
</syntaxhighlight> | |||
其实就是调用 SessionFactoryImpl 类的 openSession(): | |||
: <syntaxhighlight lang="Java" highlight=""> | |||
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 ); | |||
} | |||
... | |||
} | |||
... | |||
} | |||
</syntaxhighlight> | |||
最终返回的是 <span style="color: blue; font-size: 150%;">'''SessionImpl'''</span> 类(间接实现了 Session 接口)的对象。 | |||
=== getCurrentSession() === | |||
对于: | |||
: <syntaxhighlight lang="Java" highlight=""> | |||
Session session = sessionFactory.getCurrentSession(); | |||
</syntaxhighlight> | |||
其实就是调用 SessionFactoryImpl 类的 getCurrentSession(): | |||
# 创建一个 Configuration 对象; | |||
# 调用其 configure() 方法: | |||
#: <syntaxhighlight lang="Java" highlight=""> | |||
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; | |||
} | |||
} | |||
} | |||
... | |||
} | |||
</syntaxhighlight> | |||
<span style="color: blue">“'''current_session_context_class'''”</span>配置,见:<big>'''[[Hibernate笔记 2:配置文件详解#配置:事务管理]]'''</big> | |||
== 事务 == | == 事务 == |
2022年6月13日 (一) 05:25的最新版本
关于
对于入门的代码案例,分析其执行流程,有助于理解其设计并熟悉 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:配置文件详解#配置:事务管理