Hibernate是如何初始化连接池的呢?先看下图:
1.configuration实例化的时候,hibernate会去读取配置信息,并且将基本的配置信息(不包括实体映射信息)保存到configuration的字段properties中。
2.调用configuration的buildSessionFactory()方法,buildSessionFactory()方法又会调用SettingFactory的buildSettings(Properties props)方法。
3.buildSettings方法调用ConnectionProviderFactory的newConnectionProvider(Properties props)方法产生一个ConnectionProvider对象。
4.buildSettings方法实例化一个Setting对象,并将ConnectionProvider传递给Setting。
5.buildSettings返回一个Setting对象,然后buildSessionFactory()方法会实例化一个SessionFactoryImpl,并且将Setting对象传给SessionFactoryImpl,最后返回SessionFactoryImpl。
configuration的buildSessionFactory()方法实际上是实例化了一个连接池,并且把这个连接池交给SessionFactory管理。
ConnctionProvider是连接提供者,hibernate的数据库连接都来自它。当我们调用SessionFactoryImpl的openSession()方法时,就很容易获得数据库连接了。
Hibernate为ConnctionProvider提供了以下几个实现类:
1.C3P0ConnectionProvider。从C3P0连接池中获取数据库连接。
2.ProxoolConnectionProvider。从Proxool连接池中获取数据库连接。
3.DatasourceConnectionProvider。一般是通过JNDI从应用服务器(如JBoss)中获取数据源。
4.DriverManagerConnectionProvider。Hibernate自带的连接池。
5.UserSuppliedConnectionProvider。没有任何实现,只是抛出了异常。
到底使用哪一个呢?看看ConnectionProviderFactory.newConnectionProvider(Properties props)方法就知道了:
- public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData)
- throws HibernateException {
- ConnectionProvider connections;
- String providerClass = properties.getProperty( Environment.CONNECTION_PROVIDER );//hibernate.connection.provider_class
- if ( providerClass != null ) {
- connections = initializeConnectionProviderFromConfig( providerClass );
- }
- else if ( c3p0ConfigDefined( properties ) && c3p0ProviderPresent() ) {
- connections = initializeConnectionProviderFromConfig("org.hibernate.connection.C3P0ConnectionProvider");
- }
- else if ( properties.getProperty( Environment.DATASOURCE ) != null ) {//hibernate.connection.datasource
- connections = new DatasourceConnectionProvider();
- }
- else if ( properties.getProperty( Environment.URL ) != null ) {//hibernate.connection.url
- connections = new DriverManagerConnectionProvider();
- }
- else {
- connections = new UserSuppliedConnectionProvider();
- }
- ......
- connections.configure( properties );
- return connections;
- }
1.如果配置了hibernate.connection.provider_class属性,就会根据指定的类去实例化。属性值为C3P0ConnectionProvider或者ProxoolConnectionProvider的全限定名。
2.如果配置了hibernate.connection.datasource属性,则会实例化一个DatasourceConnectionProvider。属性值为JNDI名称。
3.如果上面两个都没配置,则会去判断是否配置hibernate.connection.url属性。如果配置了,会实例化一个DriverManagerConnectionProvider。
4.如果没有配置hibernate.connection.url属性,则实例化一个UserSuppliedConnectionProvider,实际上是抛出了异常。
我们也可以自己写一个ConnctionProvider的实现,然后配置hibernate.connection.provider_class属性,属性值为我们自己的实现类的全限定名。
版权声明:本文为博主原创文章,未经博主允许不得转载。