hibernate 不得不说的那些事--Connection Provider

ConnectionProvider 在hibernate 3.2.3中有五种实现 ,分别是DatasourceConnectionProvider、C3P0ConnectionProvider、ProxoolConnectionProvider、DriverManagerConnectionProvider、UserSuppliedConnectionProvider。

 

 DatasourceConnectionProvider:使用JNDI注册的数据源,如果要使用它,需配置hibernate.connection.datasource 属性。

 

 C3P0ConnectionProvider:使用了C3P0连接池,如果要使用它,需配置hibernate.c3p0.*属性,

 

 ProxoolConnectionProvider:使用了Proxool连接池,如果要使用它,需配置hibernate.proxool.*属性

 

 DriverManagerConnectionProvider:使用了java.sql.DriverManager,也实现了一个简单的连接池。

 

 UserSuppliedConnectionProvider:ConnectionProvider接口的实现,当请求连接的时候,抛出异常。

 

hibernate获取Connection Provider的源代码如下:

 

public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException {
		ConnectionProvider connections;
		String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);
		if ( providerClass!=null ) {
			try {
				log.info("Initializing connection provider: " + providerClass);
				connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();
			}
			catch (Exception e) {
				log.fatal("Could not instantiate connection provider", e);
				throw new HibernateException("Could not instantiate connection provider: " + providerClass);
			}
		}
		else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {
			connections = new DatasourceConnectionProvider();
		}
		else if ( properties.getProperty(Environment.C3P0_MAX_SIZE)!=null ) {
			connections = new C3P0ConnectionProvider();
		}
		else if (
			properties.getProperty(Environment.PROXOOL_XML)!=null ||
			properties.getProperty(Environment.PROXOOL_PROPERTIES)!=null ||
			properties.getProperty(Environment.PROXOOL_EXISTING_POOL)!=null
		) {
			connections = new ProxoolConnectionProvider();
		}
		else if ( properties.getProperty(Environment.URL)!=null ) {
			connections = new DriverManagerConnectionProvider();
		}
		else {
			connections = new UserSuppliedConnectionProvider();
		}

		if ( connectionProviderInjectionData != null && connectionProviderInjectionData.size() != 0 ) {
			//inject the data
			try {
				BeanInfo info = Introspector.getBeanInfo( connections.getClass() );
				PropertyDescriptor[] descritors = info.getPropertyDescriptors();
				int size = descritors.length;
				for (int index = 0 ; index < size ; index++) {
					String propertyName = descritors[index].getName();
					if ( connectionProviderInjectionData.containsKey( propertyName ) ) {
						Method method = descritors[index].getWriteMethod();
						method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } );
					}
				}
			}
			catch (IntrospectionException e) {
				throw new HibernateException("Unable to inject objects into the conenction provider", e);
			}
			catch (IllegalAccessException e) {
				throw new HibernateException("Unable to inject objects into the conenction provider", e);
			}
			catch (InvocationTargetException e) {
				throw new HibernateException("Unable to inject objects into the conenction provider", e);
			}
		}
		connections.configure(properties);
		return connections;
	}

 从源代码不难看出这么多种Connection Provider的优先顺序 :

 

自定义Connection Provider >DatasourceConnectionProvider>C3P0ConnectionProvider

> ProxoolConnectionProvider>DriverManagerConnectionProvider>UserSuppliedConnectionProvider

 

首先hibernate检测hibernate.connection.provider_class是否配置了,如果配置了,则根据该配置对应的类(必须要实现ConnectionProvider接口,含无参构造函数)名实例化。

如果hibernate.connection.provider_class没有配置,则检测hibernate.connection.datasource配置,如果配置了,则使用DatasourceConnectionProvider。

如果hibernate.connection.datasource没有配置,则检测hibernate.c3p0.max_size,如果配置了,则使用C3P0ConnectionProvider。

如果hibernate.c3p0.max_size没有配置,则检测hibernate.proxool.xml、hibernate.proxool.properties、hibernate.proxool.existing_pool的配置,只要其中任何一个配置了,则使用ProxoolConnectionProvider。

如果hibernate.proxool.xml、hibernate.proxool.properties、hibernate.proxool.existing_pool都没有配置,则检测hibernate.connection.url的配置,则使用DriverManagerConnectionProvider。

如果以上没有配置的话,则使用UserSuppliedConnectionProvider(抛出异常),提示需要提供连接。

 

猜你喜欢

转载自fufangqin1024.iteye.com/blog/2005755