2019独角兽企业重金招聘Python工程师标准>>>
原理:主要是调用目标方法时,注入不同的数据源,从而实现切换,即利用aop,而aop的实现是用代理实现的
1,给工程添加一个获取数据源的路由,并给它两个不同的数据源
@Beanpublic ThreadLocalRountingDataSource threadLocalRountingDataSource() {ThreadLocalRountingDataSource dataSource=new ThreadLocalRountingDataSource();Map targetDataSources=new HashMap();DataSource master = master();//master 数据源DataSource slave = slave();//slave 数据源targetDataSources.put(DataSources.MASTER, master);targetDataSources.put(DataSources.SLAVE, slave);dataSource.setTargetDataSources(targetDataSources);dataSource.setDefaultTargetDataSource(master);return dataSource;}
2,ThreadLocalRountingDataSource类主要是有一个决定数据源键的方法
public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceTypeManager.get();}
}
3,DataSourceTypeManager实际是一个对ThreadLocal调用的一个工具类,主要是给当前线程设置期数据源的路由键,代码如下:
import com.example.demo.enums.DataSources;public class DataSourceTypeManager {private static final ThreadLocal
}
4,编写一个aop类,决定在哪个方法需要切换数据源
@Aspect // for aop
@Component // for auto scan
@Order(0) // execute before @Transactional
public class DataSourceInterceptor { @Pointcut("execution(public * com.example.demo.service..*.getUser(..))")public void dataSourceSlave(){};@Before("dataSourceSlave()")public void before(JoinPoint jp) {DataSourceTypeManager.set(DataSources.SLAVE);}
}
彩蛋:
事务拦截器在啥时候注入了ioc容器?
观察@EnableTransactionManagement,它import了 TransactionManagementConfigurationSelector类,然后给容器注入了
AutoProxyRegistrar和ProxyTransactionManagementConfiguration,这里我们重点关注第二个类,点进去发现如下代码
给@Transactional标注的方法添加了 TransactionInterceptor 拦截器