package com.easyooo.framework.sharding; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import com.easyooo.framework.sharding.routing.RangeRoutingRule; import com.easyooo.framework.sharding.transaction.DelegatingDataSource; /** * 数据源路由,具体的路由规则由<code>RoutingRule</code>接口实现 * * @see RoutingRule * * @author Killer */ public class ModulusRoutingDataSource extends AbstractRoutingDataSource implements ApplicationContextAware { final Logger logger = LoggerFactory.getLogger(getClass()); private ModuleMatcher matcher = new ModuleMatcher(); private RoutingRule defaultRoutingRule = new RangeRoutingRule(); private Map<Module, RoutingRule> moduleRules; private ApplicationContext applicationContext; @Override public void afterPropertiesSet() { List<DataSourceKey> dskeys = RoutingConfigHolder.getInstance().getDataSourceKeys(); Map<Object, Object> targetDataSources = new HashMap<>(dskeys.size()); for (DataSourceKey dsk : dskeys) { DataSource ds = new DelegatingDataSource(applicationContext .getBean(dsk.getKey(), DataSource.class)); targetDataSources.put(dsk, ds); } setTargetDataSources(targetDataSources); super.afterPropertiesSet(); // setDefaultTargetDataSource(null); } @Override protected Object determineCurrentLookupKey() { RoutingContext context = RoutingContextHolder.getRoutingContext(); if(context == null){ throw new DsRoutingException( " No binding data source routing context parameter."); } Module module = getMatchModule(context); if(module == null){ throw new DsRoutingException(context + " Can't find the mapping module."); } DataSourceKey dsk = null; if(moduleRules != null && moduleRules.containsKey(module)){ dsk = moduleRules.get(module).routing(module, context); }else{ dsk = defaultRoutingRule.routing(module, context); } if(logger.isDebugEnabled()){ logger.debug("The dataSource is redirected to " + dsk.getKey()); } return dsk; } private Module getMatchModule(RoutingContext context){ RoutingConfigHolder rch = RoutingConfigHolder.getInstance(); Set<Module> modules = rch.getModules(); for (Module module : modules) { if(matcher.isMatch(context, module)){ return module; } } return null; } public void setModuleRules(Map<Module, RoutingRule> moduleRules) { this.moduleRules = moduleRules; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }