自我理解是这样的。首先配置事务管理器设置设置方法是否是只读创建一个DynamicDataSourceTransactionManager的类继承DataSourceTransactionManager去重写doBegin与doCleanupAfterCompletion方法。doBegin方法里根据事务设置默认类TransactionDefinition 对象调用isReadOnly()方法来判断当前事务切点的方法的读写属性(在Spring的xml或者事务注解中配置)如果为true为只读那么就使用ThreadLocal线程锁的特性设置一个标识字符串slave否则设置为master.最后调用父类的doBegin的方法。在重写的doCleanupAfterCompletion中清除掉保存的标识符,这些标识。也就是相当说在原来的方法上面多了设置线程标识的功能。然后到xml.中配置数据源。创建一个抽象类AbstractRoutingDataSource继承AbstractDataSource是DataSource的子类(也就是获得连接对象DataSource的地方)需要重写getConnection方法,还需要继承InitializingBeanSpring框架注册初始化类的接口。创建一个抽象方法determineCurrentLookupKey()该方法可以获取到dataSource的key值就可以从配置文件中设置好后存入的Map获取到对应的DataSource.如果找不到就用配置默认的数据源。创建DynamicDataSource类继承AbstractRoutingDataSource。重写determineCurrentLookupKey(),afterPropertiesSet(),determineTargetDataSource()。重点在于determineTargetDataSource()根据获取当前线程标识
1.创建DateSourceHolder类,根据ThreadLocal 特性来识别线程来获取哪个数据源。
import javax.sql.DataSource;
public class DateSourceHolder {
private static final String MASTER = "master";
private static final String SLAVE = "slave";
private static final ThreadLocal<String> dataSource = new ThreadLocal<>();
private static final ThreadLocal<DataSource> masterLocal = new ThreadLocal<>();
private static final ThreadLocal<DataSource> slaveLocal = new ThreadLocal<>();
private static void setDataSource(String dataSourceKey) {
dataSource.set(dataSourceKey);
}
private static String getDataSource() {
return dataSource.get();
}
public static boolean isMaster() {
return getDataSource() == MASTER;
}
public static boolean isSlave() {
return getDataSource() == SLAVE;
}
public static void setMaster() {
setDataSource(MASTER);
}
public static void setSlave() {
setDataSource(SLAVE);
}
public static void setSlave(DataSource dataSource) {
slaveLocal.set(dataSource);
}
public static void setMaster(DataSource dataSource) {
masterLocal.set(dataSource);
}
public static void clearDataSource() {
dataSource.remove();
masterLocal.remove();
slaveLocal.remove();
}
}
2.创建AbstractRoutingDataSource 抽象类并继承AbstractDataSource 实现InitializingBean
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.Abstr