Hibernate源码分析:入门代码流程

来自Wikioe
跳到导航 跳到搜索


关于

对于入门的代码案例,分析其执行流程,有助于理解其设计并熟悉 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();

其过程如下:

  1. 创建一个 Configuration 对象;
  2. 调用其 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();

其过程如下:

  1. 调用 Configuration 对象的 buildSessionFactory() 方法;
  2. 调用其 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():

  1. 创建一个 Configuration 对象;
  2. 调用其 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:配置文件详解#配置:事务管理

事务