經過調試,咱們發現是 spring啓動中,hibernate會裝載和初始化 全局配置, 其實就是個 Map。java
在Map中 他會初始化 org.hibernate.cfg.AvailableSettings#DATASOURCE 的key 做爲 map裏數據源的key。git
數據源初始化代碼 位於 org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl#normalizeDataAccess :spring
private void normalizeDataAccess( HashMap<?, ?> integrationSettingsCopy, MergedSettings mergedSettings, PersistenceUnitDescriptor persistenceUnit) { if ( dataSource != null ) { applyDataSource( dataSource, // we don't explicitly know null, integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } if ( integrationSettingsCopy.containsKey( DATASOURCE ) ) { final Object dataSourceRef = integrationSettingsCopy.remove( DATASOURCE ); if ( dataSourceRef != null ) { applyDataSource( dataSourceRef, null, integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } } if ( integrationSettingsCopy.containsKey( JPA_JTA_DATASOURCE ) ) { final Object dataSourceRef = integrationSettingsCopy.remove( JPA_JTA_DATASOURCE ); if ( dataSourceRef != null ) { applyDataSource( dataSourceRef, true, integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } } if ( integrationSettingsCopy.containsKey( JPA_NON_JTA_DATASOURCE ) ) { final Object dataSourceRef = integrationSettingsCopy.remove( JPA_NON_JTA_DATASOURCE ); applyDataSource( dataSourceRef, false, integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } if ( integrationSettingsCopy.containsKey( URL ) ) { // these have precedence over the JPA ones final Object integrationJdbcUrl = integrationSettingsCopy.get( URL ); if ( integrationJdbcUrl != null ) { //noinspection unchecked applyJdbcSettings( integrationJdbcUrl, NullnessHelper.coalesceSuppliedValues( () -> ConfigurationHelper.getString( DRIVER, integrationSettingsCopy ), () -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, integrationSettingsCopy ), () -> ConfigurationHelper.getString( DRIVER, mergedSettings.configurationValues ), () -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, mergedSettings.configurationValues ) ), integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } } if ( integrationSettingsCopy.containsKey( JPA_JDBC_URL ) ) { final Object integrationJdbcUrl = integrationSettingsCopy.get( JPA_JDBC_URL ); if ( integrationJdbcUrl != null ) { //noinspection unchecked applyJdbcSettings( integrationJdbcUrl, NullnessHelper.coalesceSuppliedValues( () -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, integrationSettingsCopy ), () -> ConfigurationHelper.getString( JPA_JDBC_DRIVER, mergedSettings.configurationValues ) ), integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } } if ( persistenceUnit.getJtaDataSource() != null ) { applyDataSource( persistenceUnit.getJtaDataSource(), true, integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } if ( persistenceUnit.getNonJtaDataSource() != null ) { applyDataSource( persistenceUnit.getNonJtaDataSource(), false, integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } if ( mergedSettings.configurationValues.containsKey( URL ) ) { final Object url = mergedSettings.configurationValues.get( URL ); if ( url != null && ( ! ( url instanceof String ) || StringHelper.isNotEmpty( (String) url ) ) ) { applyJdbcSettings( url, ConfigurationHelper.getString( DRIVER, mergedSettings.configurationValues ), integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } } if ( mergedSettings.configurationValues.containsKey( JPA_JDBC_URL ) ) { final Object url = mergedSettings.configurationValues.get( JPA_JDBC_URL ); if ( url != null && ( ! ( url instanceof String ) || StringHelper.isNotEmpty( (String) url ) ) ) { applyJdbcSettings( url, ConfigurationHelper.getString( JPA_JDBC_DRIVER, mergedSettings.configurationValues ), integrationSettingsCopy, mergedSettings ); // EARLY EXIT!! return; } } // any other conditions to account for? }
經過代碼能夠看出 他會優先幾個 key,看是否已經有了,有就沿用這些key裏的數據源。mybatis
個人項目目前都沒有,代碼往下走,到了 app
if ( persistenceUnit.getNonJtaDataSource() != null ) { 這一行, 發如今 org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor#getNonJtaDataSource 獲取了數據源:
轉而調用了 javax.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource :ui
發現真正的實現類是:org.springframework.orm.jpa.persistenceunit.SpringPersistenceUnitInfo 的 getNonJtaDataSource 方法。url
而後最終調用了 : org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo#getNonJtaDataSource 這個方法返回了 這個類的實例變量spa
org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo#nonJtaDataSource , 因此咱們繼續看 實例變量是如何初始化的:hibernate
最終發現 是 org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration 初始化的, 而他是由 org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration 導入的。調試
而後發現 最後DataSource來自於 spring boot autoconfig包的 org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration 類,
HibernateJpaConfiguration 直接繼承的他, 默認的DataSource對象也是 JpaBaseConfiguration 實例字段。
org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration#dataSource 而這個字段則是直接經過 類構造方法 讓spring自動ioc的。
題外話:關於 JPA實現相似mybatis的動態效果,能夠參考下大佬的開源: https://gitee.com/it00021hot/fenix