org.hibernate.connection包分析--ConnectionProviderFactory

本文深入探讨了Hibernate的ConnectionProviderFactory类,详细解析了如何根据配置创建ConnectionProvider。主要关注`newConnectionProvider()`方法,特别是如何处理Properties和自定义的连接提供者扩展。通过对反射技术的运用,解释了当用户扩展ConnectionProvider接口时,如何注入自定义配置参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          这个类是一个工厂类,它统一返回一个ConnectionProvider 接口供外界调用。          

       首先看它的三个newConnectionProvider()方法:

public static ConnectionProvider newConnectionProvider() throws HibernateException { return newConnectionProvider( Environment.getProperties() ); } public static ConnectionProvider newConnectionProvider(Properties properties) throws HibernateException { return newConnectionProvider( properties, null ); } public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException { ...... ...... }

     实际上最开始加载的是public static ConnectionProvider newConnectionProvider(Properties properties, Map

connectionProviderInjectionData) throws HibernateException这个方法,所以我们研究这个方法即可。

   我们看看这个方法的参数,有两个,properties和connectionProviderInjectionData,一个是Properties 类型的,一

个是Map类型的,第一个参数是HIBERNATE.CFG或者HIBERNATE.PROPERTIES属性文件中的各个属性,第二个参数是用户注入

的属性值,实际上在调用这个方法的时候,connectionProviderInjectionData是为空的,也就是说,在提供了

HIBERNATE.CFG或者HIBERNATE.PROPERTIES等配置文件的时候,是不需要用户来注入数据的,除非用户自己有特殊需要,定

义自己的配置文件,则可以注入一个Map型的参数来完成配置的初始化。

   该方法首先定义 connections这样一个ConnectionProvider类型的接口变量,并判断

Environment.CONNECTION_PROVIDER配置是否为空,也就是判断是否配置了连接池,所以前面提到过,真正判断是否使用连

接池是在这个类里面。若不为空,执行connections = (ConnectionProvider) ReflectHelper.classForName

(providerClass).newInstance();       然后检测Environment.DATASOURCE参数配置,若不为空,则说明配置了数据源的连接,则connections 接口引用的是它

的实现类——DatasourceConnectionProvider。

   检测Environment.URL参数配置,若不为空,说明配置了数据库连接的URL,则connections 接口引用的是它的实现类—

—DriverManagerConnectionProvider。

   若用户自己扩展了ConnectionProvider 接口,也就是修改了UserSuppliedConnectionProvider类,则connections 接

口引用的是它的实现类——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;

这段代码是不会执行的。因为在调用public static ConnectionProvider newConnectionProvider(Properties

properties) throws HibernateException 方法的时候,方法里面的return newConnectionProvider( properties, null

)第二个参数始终为空,,所以程序会向下直接执行connections.configure(properties)方法,该方法在前面介绍了,是

初始化了最基本的连接配置。但是这段代码里面使用了反射的技术,是值得关注的,我们可以看看如果用户自己扩展了

ConnectionProvider 接口,那么将如何注入自己的配置参数,去初始化最基本的连接配置。     首先通过Introspector.getBeanInfo( connections.getClass() )返回一个BeanInfo 接口,来获取有关其 bean 的方

法、属性、事件等显式信息。     PropertyDescriptor[] descritors = info.getPropertyDescriptors();通过BeanInfo 的getPropertyDescriptors()

方法来获取它的支持的可编辑属性的 PropertyDescriptor 数组。并一个个判断,注入属性的键值是否与该类中的属性同

名,若同名则通过Method method = descritors[index].getWriteMethod()来获取其属性的setter方法,通过

method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } )来设定其

属性的值,也就达到了注入数据的目的。     HIBERNATE中使用了大量的反射技术,它使用 Java 反射机制而不是字节码增强程序来实现透明性。

    以上的代码不执行,而直接执行connections.configure(properties)方法,初始化了最基本的连接配置,直接返回该 ConnectionProvider 接口。

    getConnectionProperties( props )方法在前面已经介绍。

    这样,  org.hibernate.connection包分析完了。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值