springboot多数据源《二》
package datachange.mulit.config.config; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * * 配置多个库 * * */ @Configuration @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class }) public class DataSourceConfig { @Bean @ConfigurationProperties(prefix="spring.datasource.mysql0") public DataSource mysql0() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.mysql1") public DataSource mysql1() { return DataSourceBuilder.create().build(); } @Bean(name = "dynamicDataSource") @Primary//使用的时候,只能有一个数据源的事务 public DynamicDataSource dataSource(@Qualifier("mysql0") DataSource remoteDataSource,@Qualifier("mysql1") DataSource localDataSource) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceType.MYSQL0.name(), remoteDataSource); targetDataSources.put(DataSourceType.MYSQL1.name(), localDataSource); return new DynamicDataSource(remoteDataSource, targetDataSources); } //设置默认mysql0数据库事务 这与数据源默认DynamicDataAnnonation保持一致 //多数据源事务保持一致 //给数据源配置对应的事务管理器,利用编程式事务控制, @Bean @Primary public DataSourceTransactionManager dataSourceTransactionManager0(){ DataSourceTransactionManager dataSourceTransactionManager=new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(mysql0()); return dataSourceTransactionManager; } @Bean("getTransactionTemplate0") @Primary public TransactionTemplate getTransactionTemplate0(){ return new TransactionTemplate(dataSourceTransactionManager0()); } @Bean public DataSourceTransactionManager dataSourceTransactionManager1(){ DataSourceTransactionManager dataSourceTransactionManager=new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(mysql1()); return dataSourceTransactionManager; } @Bean("getTransactionTemplate1") public TransactionTemplate getTransactionTemplate1(){ return new TransactionTemplate(dataSourceTransactionManager1()); } }
package datachange.mulit.config.config; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.Map; /** * 集成spring事务 */ public class DynamicDataSource extends AbstractRoutingDataSource { private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>(); public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) { super.setDefaultTargetDataSource(defaultTargetDataSource); super.setTargetDataSources(targetDataSources); // afterPropertiesSet()方法调用时用来将targetDataSources的属性写入resolvedDataSources中的 super.afterPropertiesSet(); } public static void setDataSourceKey(String dataSource) { dataSourceKey.set(dataSource); } public static void toDefault() { dataSourceKey.remove(); } @Override protected Object determineCurrentLookupKey() { return dataSourceKey.get(); } }
/** * 切面 */ @Aspect @Component public class DynamicDataSourceAspect { @Pointcut("@annotation(security.config.dynamic.DynamicSource)") public void dataSourcePointCut(){ } @Around("dataSourcePointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { String dsKey = getDSAnnotation(joinPoint).value(); DynamicDataSource.setDataSourceKey(dsKey); try{ return joinPoint.proceed(); }finally { DynamicDataSource.toDefault(); } } /** * 根据类或方法获取数据源注解 */ private DynamicSource getDSAnnotation(ProceedingJoinPoint joinPoint){ Class<?> targetClass = joinPoint.getTarget().getClass(); DynamicSource dsAnnotation = targetClass.getAnnotation(DynamicSource.class); // 先判断类的注解,再判断方法注解 if(Objects.nonNull(dsAnnotation)){ return dsAnnotation; }else{ MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); return methodSignature.getMethod().getAnnotation(DynamicSource.class); } } }
使用 /** * 查询master库User */ @DynamicSource(DataSourceType.MYSQL0) public List getMasterUser() { return null; } /** * 查询slave库User */ @DynamicSource(DataSourceType.MYSQL1) public List getSlaveUser() { return null; }
注解 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface DynamicSource { String value() default MYSQL0; }
简要介绍多数据源,声明式事务
源码地址:https://gitee.com/wbweb/spring-boot-mulit-transaltion
一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰