
單個資料源綁定給sessionFactory,再在Dao層操作,若多個資料源的話,那不是就成了下圖:
可見,sessionFactory都寫死在了Dao層,若我再添加個資料源的話,則又得添加一個sessionFactory。是以比較好的做法應該是下圖:
二、實作原理
1、擴充Spring的AbstractRoutingDataSource抽象類(該類充當了DataSource的路由中介, 能有在運作時, 根據某種key值來動态切換到真正的DataSource上。)
從AbstractRoutingDataSource的源碼中:
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean
我們可以看到,它繼承了AbstractDataSource,而AbstractDataSource不就是javax.sql.DataSource的子類,So我們可以分析下它的getConnection方法:
public Connection getConnection() throws SQLException {
return determineTargetDataSource().getConnection();
}
public Connection getConnection(String username, String password) throws SQLException {
return determineTargetDataSource().getConnection(username, password);
}
擷取連接配接的方法中,重點是determineTargetDataSource()方法,看源碼:
protected DataSource determineTargetDataSource() {
Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = this.resolvedDataSources.get(lookupKey);
if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
dataSource = this.resolvedDefaultDataSource;
}
if (dataSource == null) {
throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
}
return dataSource;
}
上面這段源碼的重點在于determineCurrentLookupKey()方法,這是AbstractRoutingDataSource類中的一個抽象方法,而它的傳回值是你所要用的資料源dataSource的key值,有了這個key值,resolvedDataSource(這是個map,由配置檔案中設定好後存入的)就從中取出對應的DataSource,如果找不到,就用配置預設的資料源。