Springboot 多数据源动态切换 以AOP切点方式实现

com.example

demo

0.0.1-SNAPSHOT

demo

Demo project for Spring Boot

<java.version>1.8</java.version>

org.springframework.boot

spring-boot-starter

org.springframework.boot

spring-boot-starter-web

mysql

mysql-connector-java

com.alibaba

druid-spring-boot-starter

1.1.9

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.1.0

org.aspectj

aspectjweaver

1.8.9

org.aspectj

aspectjrt

1.8.9

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-maven-plugin

然后接下来是application.yml文件:

spring:

datasource:

type: com.alibaba.druid.pool.DruidDataSource

driverClassName: com.mysql.jdbc.Driver

druid:

#第一个数据源连接信息

one:

url: jdbc:mysql://localhost:3306/game_message?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8

username: root

password: root

#第二个数据源连接信息

two:

url: jdbc:mysql://localhost:3306/game_message_cluster?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8

username: root

password: root

#数据库连接池信息

initial-size: 10

max-active: 100

min-idle: 10

max-wait: 60000

pool-prepared-statements: true

max-pool-prepared-statement-per-connection-size: 20

time-between-eviction-runs-millis: 60000

min-evictable-idle-time-millis: 300000

validation-query: SELECT 1 FROM DUAL

test-while-idle: true

test-on-borrow: false

test-on-return: false

stat-view-servlet:

enabled: true

url-pattern: /druid/*

filter:

stat:

log-slow-sql: true

slow-sql-millis: 1000

merge-sql: true

wall:

config:

multi-statement-allow: true

#配置下项目端口

server:

port: 8023

#mybatis扫描文件路径

mybatis:

config-location: classpath:mybatis/mybatis-config.xml

mapper-locations: classpath:mybatis/mapper/*.xml

#将日志文件生成到系统盘路径

logging:

path: F:\logtest\log

#简单设置一下日志等级

level:

web: debug

接下来我们罗列下数据源的名字,这里简单用ONE 、TWO 表示,DataSourceNames.java:

/**

  • @Author : JCccc

  • @CreateTime : 2019/8/28

  • @Description :

**/

public interface DataSourceNames {

String ONE = “ONE”;

String TWO = “TWO”;

}

接着创一个自定义注解,作为aop切点使用,DataSource.java:

import java.lang.annotation.*;

/**

  • @Author : JCccc

  • @CreateTime : 2019/8/28

  • @Description :

**/

@Documented

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

public @interface DataSource {

String value() default DataSourceNames.ONE; //默认值为ONE,因为后面我们选择配置这个ONE为默认数据库

}

然后是配置AOP切点,DataSourceAspect.java:

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.Ordered;

import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

/**

  • @Author : JCccc

  • @CreateTime : 2019/8/28

  • @Description :

**/

@Aspect

@Component

public class DataSourceAspect implements Ordered {

protected Logger logger = LoggerFactory.getLogger(getClass());

/**

  • 切点: 所有配置 DataSource 注解的方法

*/

@Pointcut(“@annotation(com.example.demo.config.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);

// 通过判断 DataSource 中的值来判断当前方法应用哪个数据源

DynamicDataSource.setDataSource(ds.value());

logger.info("AOP切换数据源成功,数据源为: " + ds.value());

logger.info("set datasource is " + ds.value());

try {

return point.proceed();

} finally {

DynamicDataSource.clearDataSource();

logger.info(“clean datasource”);

}

}

@Override

public int getOrder() {

return 1;

}

}

到这里切点AOP的相关配置已经完毕了,接下来到核心的动态数据源配置。

先创建手动切换数据源的核心方法类,DynamicDataSource.java:

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;

import java.util.Map;

/**

  • @Author : JCccc

  • @CreateTime : 2019/8/28

  • @Description :

**/

public class DynamicDataSource extends AbstractRoutingDataSource {

private static final ThreadLocal contextHolder = new ThreadLocal<>();

/**

  • 配置DataSource, defaultTargetDataSource为主数据库

*/

public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {

super.setDefaultTargetDataSource(defaultTargetDataSource);

super.setTargetDataSources(targetDataSources);

super.afterPropertiesSet();

}

@Override

protected 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();

}

}

然后是用于读取配置信息多数据源,并将其载入的类,DynamicDataSourceConfig.java:

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

import java.util.HashMap;

import java.util.Map;

/**

  • @Author : JCccc

  • @CreateTime : 2019/8/28

  • @Description :

**/

@Configuration

public class DynamicDataSourceConfig {

/**

  • 创建 DataSource Bean

  • */

@Bean

@ConfigurationProperties(“spring.datasource.druid.one”)

public DataSource oneDataSource(){

DataSource dataSource = DruidDataSourceBuilder.create().build();

return dataSource;

}

@Bean

@ConfigurationProperties(“spring.datasource.druid.two”)

public DataSource twoDataSource(){

DataSource dataSource = DruidDataSourceBuilder.create().build();

return dataSource;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

部分内容:

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注
目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

[外链图片转存中…(img-xNdjmgA2-1712109084149)]

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

[外链图片转存中…(img-OoKaIY04-1712109084149)]

部分内容:

[外链图片转存中…(img-7pmFd9o4-1712109084150)]

[外链图片转存中…(img-rSl6PQg3-1712109084150)]

[外链图片转存中…(img-UAtpRrFx-1712109084150)]

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot是一个用于简化Spring应用开发的框架,可以方便地实现多数据源动态切换功能。 在Spring Boot中,通过配置多个数据源bean,可以实现多数据源的使用。首先,在application.properties或application.yml文件中配置多个数据源的相关属性,例如数据库连接信息、驱动程序等。然后,在Spring Boot的配置类中,通过@Bean注解将数据源bean配置到Spring容器中。 为了实现动态切换数据源,可以使用ThreadLocal或者AOP进行数据源切换。首先,可以定义一个DataSourceContextHolder类,使用ThreadLocal来存储当前线程使用的数据源标识。然后,可以在需要切换数据源的地方,通过调用DataSourceContextHolder的setDataSourceKey方法,设置当前线程使用的数据源标识。在数据访问层的代码中,可以通过调用DataSourceContextHolder的getDataSourceKey方法获取当前线程使用的数据源标识,然后根据该标识来获取对应的数据源bean。 除了使用ThreadLocal,还可以使用AOP实现数据源切换。可以定义一个切面,通过在切面中获取注解或者方法名来确定使用的数据源,然后通过切换数据源方式实现动态切换。 通过以上的方式,就可以实现Spring Boot多数据源动态切换功能。不同的数据源可以根据自己的需求和业务场景进行配置和使用,提高系统的扩展性和灵活性。 ### 回答2: Spring Boot提供了方便的配置和集成多数据源,并且支持动态切换数据源。下面将通过一个简单的示例来说明如何在Spring Boot实现多数据源动态切换。 首先,在pom.xml文件中添加Spring Boot数据源相关的依赖项,比如Spring Boot Starter、MyBatis、Druid等。然后,在application.properties文件中配置数据源的相关信息,包括数据库的URL、用户名、密码等。 接下来,创建多个数据源的配置类,通过@Configuration注解将其标记为配置类,并使用@Bean注解来创建数据源对象。在创建数据源对象时,可以使用DruidDataSource或者其他适配的数据源类。 在创建数据源配置类时,可以使用@Primary注解来指定一个主数据源,该主数据源将作为默认数据源使用。对于其他数据源,可以使用@Qualifier注解进行标识。 然后,在创建MyBatis的SqlSessionFactoryBean时,使用@MapperScan注解来扫描并加载Mapper接口。在其中配置数据源,可以通过注入的方式获取数据源对象,并将其设置到SqlSessionFactoryBean中。 最后,在需要切换数据源的地方,可以通过使用AOP切面和动态切换数据源方式实现。可以创建一个DataSourceAspect切面类,在其中定义切点和通知,通过在方法上添加@DataSource注解来指定要切换数据源。在通知方法中,通过读取注解上的参数来确定要切换数据源,并将其设置到ThreadLocal变量中。 总结起来,Spring Boot多数据源动态切换的步骤包括添加依赖项、配置数据源、创建数据源配置类、配置MyBatis的SqlSessionFactoryBean以及使用AOP实现动态切换数据源。通过这些步骤,我们可以在Spring Boot中轻松实现多数据源动态切换。 ### 回答3: 在Spring Boot实现多数据源动态切换可以通过以下步骤实现: 1. 配置数据源:在application.properties或yml文件中配置多个数据源的连接信息,每个数据源都有独立的数据源配置属性。 2. 创建数据源工厂:使用Spring的Bean注解创建多个数据源对象,并分别设置其相关属性。 3. 创建数据源路由器:创建一个数据源路由器类,该类包含一个ThreadLocal变量,用于保存当前线程所使用的数据源标识。 4. 创建数据源切换注解:使用自定义注解方式,通过在Service层的方法上加上注解,来选择对应的数据源。 5. 创建切面:使用AOP方式,在方法执行前获取选择的数据源标识,并存入数据源路由器的ThreadLocal变量中。 6. 创建数据源切换切入点:在切面中设置一个切入点,用于匹配加上数据源切换注解的方法。 7. 配置数据源切面:使用Spring的Bean注解配置切面类。 8. 启动类中配置数据源切换:在启动类中添加@EnableAspectJAutoProxy注解来开启AOP,同时使用@Import注解引入切面类。 9. 使用数据源切换注解:在Service层的方法上加上数据源切换注解,指定使用哪个数据源。 通过以上步骤,就可以在使用Spring Boot实现多数据源动态切换。在需要切换数据源的地方,只需要使用自定义的注解来指定数据源切换的过程由切面和数据源路由器来完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值