springboot配置多数据源AOP

本文介绍如何在SpringBoot中配置并使用AOP实现动态数据源切换,包括pom.xml依赖设置、YML配置、自定义注解、动态数据源类及切面类的实现,展示了通过注解在业务层选择不同数据源的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整理springboot配置多数据源,由AOP实现

先看pom.xml,springboot版本2.1.4

        <dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.11</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.1.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>

再看yml文件

项目结构:

自定义注解 TargetDs:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface TargetDs {
    String value() default "";
}
DataSourceConfig.Class:
@Configuration
public class DataSourceConfig {
    @Bean(name = "db")
    @ConfigurationProperties(prefix = "spring.datasource.db")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }
    @Primary
    @Bean(name = "dynamicDS1")
    public DataSource dataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默认
        dynamicDataSource.setDefaultTargetDataSource(dataSource1());

        Map<Object, Object> dsMap = new HashMap();
        dsMap.put("db", dataSource1());
        dsMap.put("db2", dataSource2());

        dynamicDataSource.setTargetDataSources(dsMap);
        return dynamicDataSource;
    }
    /**
     * 配置@Transactional注解事物
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}
DataSourceContextHolder.Class
     /**
     * 默认数据源
     */
    public static final String DEFAULT_DS = "db";
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    public static void setDB(String dbType) {
        contextHolder.set(dbType);
    }
    public static String getDB() {
        return (contextHolder.get());
    }
    public static void clearDB() {
        contextHolder.remove();
    }
DynamicDataSource.Class比较关键的类
public class DynamicDataSource extends AbstractRoutingDataSource  {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDB();
    }
}
DynamicAspect.Class
@Aspect
@Component
public class DynamicAspect {
    @Before("@annotation(TargetDs)")
    public void before(JoinPoint joinPoint) throws NoSuchMethodException {

        Class<?> className = joinPoint.getTarget().getClass();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

        String methodName = methodSignature.getName();

        Class[] parameterTypes = methodSignature.getParameterTypes();
        Method method = className.getMethod(methodName, parameterTypes);

        String dataSource = DataSourceContextHolder.DEFAULT_DS;

        if (null != method && method.isAnnotationPresent(TargetDs.class)) {
            TargetDs annotation = method.getAnnotation(TargetDs.class);
            dataSource = annotation.value();
        }
        DataSourceContextHolder.setDB(dataSource);
    }
    @After("@annotation(TargetDs)")
    public void afterSwitchDS(JoinPoint point) {
        DataSourceContextHolder.clearDB();

    }
}

以上就是aop动态切换数据源,默认加载db,加注解可以加载db2,原本想在mapper的接口里去用注解,但是发现有问题,后续研究出来会更新一下。

看一下如何使用:

@Service
public class UserService implements IUserService {

    @Autowired
    private UserMapper baseDao;

    @TargetDs("db2")
    public User getUser(){
        return baseDao.findUser();
    }
}

整体上比较简单,主要就是利用aop。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值