mybatis 動態數據源核心--AbstractRoutingDataSource

  1 public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
  2     @Nullable
  3     private Map<Object, Object> targetDataSources;
  4     @Nullable
  5     private Object defaultTargetDataSource;
  6     private boolean lenientFallback = true;
  7     private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
  8     @Nullable
  9     private Map<Object, DataSource> resolvedDataSources;
 10     @Nullable
 11     private DataSource resolvedDefaultDataSource;
 12 
 13     public AbstractRoutingDataSource() {
 14     }
 15 
 16     //設置當前所支持的數據源列表 是key-datasource列表形式哦  通過切換key就切換了數據源
 17     public void setTargetDataSources(Map<Object, Object> targetDataSources) {
 18         this.targetDataSources = targetDataSources;
 19     }
 20 
 21     //設置默認的數據源
 22     public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
 23         this.defaultTargetDataSource = defaultTargetDataSource;
 24     }
 25 
 26     public void setLenientFallback(boolean lenientFallback) {
 27         this.lenientFallback = lenientFallback;
 28     }
 29 
 30     public void setDataSourceLookup(@Nullable DataSourceLookup dataSourceLookup) {
 31         this.dataSourceLookup = (DataSourceLookup)(dataSourceLookup != null ? dataSourceLookup : new JndiDataSourceLookup());
 32     }
 33     
 34     public void afterPropertiesSet() {
 35         if (this.targetDataSources == null) {
 36             throw new IllegalArgumentException("Property 'targetDataSources' is required");
 37         } else {
 38             this.resolvedDataSources = CollectionUtils.newHashMap(this.targetDataSources.size());
39 this.targetDataSources.forEach((key, value) -> {//解析datasource 40 Object lookupKey = this.resolveSpecifiedLookupKey(key); 41 DataSource dataSource = this.resolveSpecifiedDataSource(value); 42 this.resolvedDataSources.put(lookupKey, dataSource); 43 }); 44 if (this.defaultTargetDataSource != null) { 45 this.resolvedDefaultDataSource = this.resolveSpecifiedDataSource(this.defaultTargetDataSource); 46 } 47 48 } 49 } 50 51 protected Object resolveSpecifiedLookupKey(Object lookupKey) { 52 return lookupKey; 53 } 54 55 protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException {
//datasource 可以是DataSource實現類 也可以是string參數
56 if (dataSource instanceof DataSource) { 57 return (DataSource)dataSource; 58 } else if (dataSource instanceof String) { 59 return this.dataSourceLookup.getDataSource((String)dataSource); 60 } else { 61 throw new IllegalArgumentException("Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource); 62 } 63 } 64 65 public Map<Object, DataSource> getResolvedDataSources() { 66 Assert.state(this.resolvedDataSources != null, "DataSources not resolved yet - call afterPropertiesSet"); 67 return Collections.unmodifiableMap(this.resolvedDataSources); 68 } 69 70 @Nullable 71 public DataSource getResolvedDefaultDataSource() { 72 return this.resolvedDefaultDataSource; 73 } 74 75 public Connection getConnection() throws SQLException { 76 return this.determineTargetDataSource().getConnection(); 77 } 78 79 public Connection getConnection(String username, String password) throws SQLException { 80 return this.determineTargetDataSource().getConnection(username, password); 81 } 82 83 public <T> T unwrap(Class<T> iface) throws SQLException { 84 return iface.isInstance(this) ? this : this.determineTargetDataSource().unwrap(iface); 85 } 86 87 public boolean isWrapperFor(Class<?> iface) throws SQLException { 88 return iface.isInstance(this) || this.determineTargetDataSource().isWrapperFor(iface); 89 } 90 91 protected DataSource determineTargetDataSource() { 92 Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); 93 //動態獲取當前數據源 key , determineCurrentLookupKey 是關鍵,我們可以自己實現的切換邏輯 94 Object lookupKey = this.determineCurrentLookupKey(); 95 DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey); 96 if (dataSource == null && (this.lenientFallback || lookupKey == null)) { 97 dataSource = this.resolvedDefaultDataSource; 98 } 99 100 if (dataSource == null) { 101 throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]"); 102 } else { 103 return dataSource; 104 } 105 } 106 107 //這是抽象方法,需要自己實現哦 108 @Nullable 109 protected abstract Object determineCurrentLookupKey(); 110 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章