赞
踩
源码:https://download.csdn.net/download/asd792520/11830815
自行添加mysql或者oracle驱动包
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description 自定义多数据源切换注解
- */
- @Target({ ElementType.METHOD, ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- public @interface DataSource {
-
- public DataSourceType value() default DataSourceType.MASTER;
- }
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description 数据源
- */
- public enum DataSourceType {
-
- /**
- * 主库
- */
- MASTER,
-
- /**
- * 从库
- */
- SLAVE
- }
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description druid 配置属性
- */
- @Configuration
- public class DruidProperties {
-
- @Value("${spring.datasource.druid.initialSize}")
- private int initialSize;
-
- @Value("${spring.datasource.druid.minIdle}")
- private int minIdle;
-
- @Value("${spring.datasource.druid.maxActive}")
- private int maxActive;
-
- @Value("${spring.datasource.druid.maxWait}")
- private int maxWait;
-
- @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
- private int timeBetweenEvictionRunsMillis;
-
- @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
- private int minEvictableIdleTimeMillis;
-
- @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
- private int maxEvictableIdleTimeMillis;
-
- @Value("${spring.datasource.druid.validationQuery}")
- private String validationQuery;
-
- @Value("${spring.datasource.druid.testWhileIdle}")
- private boolean testWhileIdle;
-
- @Value("${spring.datasource.druid.testOnBorrow}")
- private boolean testOnBorrow;
-
- @Value("${spring.datasource.druid.testOnReturn}")
- private boolean testOnReturn;
-
- public DruidDataSource dataSource(DruidDataSource datasource)
- {
- /** 配置初始化大小、最小、最大 */
- datasource.setInitialSize(initialSize);
- datasource.setMaxActive(maxActive);
- datasource.setMinIdle(minIdle);
-
- /** 配置获取连接等待超时的时间 */
- datasource.setMaxWait(maxWait);
-
- /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
- datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-
- /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
- datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
- datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
-
- /**
- * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
- */
- datasource.setValidationQuery(validationQuery);
- /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
- datasource.setTestWhileIdle(testWhileIdle);
- /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
- datasource.setTestOnBorrow(testOnBorrow);
- /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
- datasource.setTestOnReturn(testOnReturn);
- return datasource;
- }
- }
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description druid 配置多数据源
- */
-
- @Configuration
- public class DruidConfig {
-
- @Bean
- @ConfigurationProperties("spring.datasource.druid.master")
- public DataSource masterDataSource(DruidProperties properties) {
- DruidDataSource build = DruidDataSourceBuilder.create().build();
- return properties.dataSource(build);
- }
-
- @Bean
- @ConfigurationProperties("spring.datasource.druid.slave")
- @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
- public DataSource slaveDataSource(DruidProperties properties) {
- DruidDataSource build = DruidDataSourceBuilder.create().build();
- return properties.dataSource(build);
- }
-
- @Bean(name = "dynamicDataSource")
- @Primary
- public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource)
- {
- Map<Object, Object> targetDataSources = new HashMap<>();
- targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
- targetDataSources.put(DataSourceType.SLAVE.name(), slaveDataSource);
- return new DynamicDataSource(masterDataSource, targetDataSources);
- }
- }
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description 数据源切换处理
- */
- @Slf4j
- public class DynamicDataSourceContextHolder {
-
- /**
- * 使用ThreadLocal维护变量,ThreadLoacl为每个使用该变量的线程提供独立变量副本
- * 所以每个线程都可以独立的改变自己的副本,而不影响其他线程对应的副本
- */
- private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
-
- /**
- * 设置数据源变量
- * @param dataSourceType
- */
- public static void setDataSourceType(String dataSourceType) {
- log.info("切换到{}数据源", dataSourceType);
- CONTEXT_HOLDER.set(dataSourceType);
- }
-
- /**
- * 获取数据源变量
- */
- public static String getDataSourceType() {
- return CONTEXT_HOLDER.get();
- }
-
- /**
- * 清楚数据源变量
- */
- public static void clearDataSourceType() {
- CONTEXT_HOLDER.remove();
- }
- }
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description 动态数据源
- */
- public class DynamicDataSource extends AbstractRoutingDataSource {
-
- public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
- super.setDefaultTargetDataSource(defaultTargetDataSource);
- super.setTargetDataSources(targetDataSources);
- super.afterPropertiesSet();
- }
-
- @Override
- protected Object determineCurrentLookupKey() {
- return DynamicDataSourceContextHolder.getDataSourceType();
- }
- }
- /**
- * Created by qiuzhb on 2019/9/30.
- *
- * @Description 多数据源处理
- */
- @Aspect
- @Order(1)
- @Component
- @Slf4j
- public class DataSourceAcpect {
-
- @Pointcut("@annotation(com.qiuzhb.annotation.DataSource)" +
- "|| @within(com.qiuzhb.annotation.DataSource)")
- public void dsPoincut() {
-
- }
-
- @Around("dsPoincut()")
- public Object around(ProceedingJoinPoint point) throws Throwable {
- DataSource dataSource = getDataSource(point);
- if (dataSource != null) {
- DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
- }
- try {
- return point.proceed();
- } finally {
- // 销毁数据源,在执行方法之后
- DynamicDataSourceContextHolder.clearDataSourceType();
- }
-
- }
-
- /**
- * 获取需要切换的数据源
- * @param joinPoint
- * @return
- */
- public DataSource getDataSource(ProceedingJoinPoint joinPoint) {
- MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- Class<? extends Object> aClass = joinPoint.getTarget().getClass();
- DataSource targetDataSource = aClass.getAnnotation(DataSource.class);
- if (targetDataSource != null ) {
- return targetDataSource;
- } else {
- Method method = signature.getMethod();
- DataSource methodDataSource = method.getAnnotation(DataSource.class);
- return methodDataSource;
- }
- }
- }
在service类中的方法上打上注解
- @DataSource(DataSourceType.SLAVE)
- public int getCount() {
- int count = dao.getCount();
- return count;
- }
编写test测试
- @Test
- public void dataSourceTest() {
- int count = service.getCount();
- System.out.println(count);
- }
结果:
ps:如有问题,还望不吝赐教!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。