SpringBoot整合多数据源(aop,自定义注解实现)
https://blog.csdn.net/y_index/article/details/97806367
1、数据库配置
server:port: 10000spring:datasource:initialize: falsename: MySQLdruid:first:url: jdbc:mysql://192.168.199.86:3306/aoshop?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8username: ddb_devpassword: 123456second:url: jdbc:mysql://192.168.199.45:3306/aoshop?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8username: test_allpassword: 123456type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.DriverinitialSize: 5maxActive: 1000minIdle: 5maxWait: 10000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 30000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20filters: stat,wall,log4jconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000logSlowSql: trueswagger:host: 127.0.0.1:9000enable: truelogging:config: classpath:logs.xmllevel:com.jinglitong.shop.mapper: debug
2、注解类
@Target({ ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface DataSource {String name() default "";
3、配置数据源
public interface DataSourceNames {String FIRST = "first";String SECOND = "second";}
4、动态数据源加载
public class DynamicDataSource extends AbstractRoutingDataSource {//用来保存数据源与获取数据源private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey() {return getDataSource();}public static void setDataSource(String dataSource) {contextHolder.set(dataSource);}public static String getDataSource() {return contextHolder.get();}public static void clearDataSource() {contextHolder.remove();}}
5、把信息加载到配置中
@Configuration@MapperScan("com.jinglitong.shop.mapper")public class DynamicDataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.druid.first")public DataSource firstDataSource(){return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.druid.second")public DataSource secondDataSource(){return DruidDataSourceBuilder.create().build();}@Bean@Primarypublic DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceNames.FIRST, firstDataSource);targetDataSources.put(DataSourceNames.SECOND, secondDataSource);return new DynamicDataSource(firstDataSource, targetDataSources);}}
6、aop代理一下
@Aspect@Componentpublic class DataSourceAspect implements Ordered{protected Logger logger = LoggerFactory.getLogger(getClass());@Pointcut("@annotation(com.jinglitong.shop.datasource.DataSource)")//这个注解DataSource的包名public void dataSourcePointCut() {}@Around("dataSourcePointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();DataSource ds = method.getAnnotation(DataSource.class);if(ds == null){DynamicDataSource.setDataSource(DataSourceNames.FIRST);System.out.println("FIRST");logger.debug("set datasource is " + DataSourceNames.FIRST);}else {System.out.println(ds.name());DynamicDataSource.setDataSource(ds.name());logger.debug("set datasource is " + ds.name());}try {return point.proceed();} finally {DynamicDataSource.clearDataSource();logger.debug("clean datasource");}}@Overridepublic int getOrder() {return 1;}}
7、在service层使用自定义注解
8、启动类
