Merge branch 'feat/dev_mysql_starter_v1' into test

This commit is contained in:
xiang
2025-07-27 23:48:24 +08:00
11 changed files with 175 additions and 3 deletions

11
pom.xml
View File

@@ -12,6 +12,7 @@
<module>xservice-common</module> <module>xservice-common</module>
<module>xservice-cache</module> <module>xservice-cache</module>
<module>xservice-third-part</module> <module>xservice-third-part</module>
<module>xservice-mysql-starter</module>
</modules> </modules>
<properties> <properties>
@@ -71,13 +72,17 @@
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version> <version>${mybatis-spring-boot.version}</version>
</dependency> </dependency>
<!-- Redis -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<!-- Redis -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- </dependency>-->
<!-- RocketMQ --> <!-- RocketMQ -->
<dependency> <dependency>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>

View File

@@ -8,6 +8,7 @@
<artifactId>xservice-basic</artifactId> <artifactId>xservice-basic</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<version>1.0.1-SNAPSHOT</version>
<artifactId>xservice-common</artifactId> <artifactId>xservice-common</artifactId>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiang</groupId>
<artifactId>xservice-basic</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xservice-mysql-starter</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -0,0 +1,13 @@
package com.xiang.xservice.mysql.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamicDataSource {
// 数据源标识
String value();
}

View File

@@ -0,0 +1,31 @@
package com.xiang.xservice.mysql.aspect;
import com.xiang.xservice.mysql.annotation.DynamicDataSource;
import com.xiang.xservice.mysql.config.DynamicDataSourceContext;
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;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(com.xiang.xservice.mysql.annotation.DynamicDataSource)")
public void dataSourcePointCut() {}
@Around("dataSourcePointCut()")
public Object switchDataSource(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
DynamicDataSource ds = signature.getMethod().getAnnotation(DynamicDataSource.class);
if (ds != null) {
DynamicDataSourceContext.set(ds.value());
}
try {
return point.proceed();
} finally {
DynamicDataSourceContext.clear();
}
}
}

View File

@@ -0,0 +1,37 @@
package com.xiang.xservice.mysql.config;
import com.google.common.collect.Maps;
import com.xiang.xservice.mysql.entity.DynamicDataSourceProperties;
import com.xiang.xservice.mysql.service.DynamicRoutingDataSource;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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 javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDataSourceConfig {
@Bean
@Primary
public DataSource dataSource(DynamicDataSourceProperties props) {
Map<Object, Object> targetDataSources = Maps.newHashMap();
props.getDatasource().forEach((key, config) -> {
DataSourceBuilder<?> builder = DataSourceBuilder.create()
.url(config.getUrl())
.username(config.getUsername())
.password(config.getPassword())
.driverClassName(config.getDriverClassName());
targetDataSources.put(key, builder.build());
});
DynamicRoutingDataSource routing = new DynamicRoutingDataSource();
routing.setDefaultTargetDataSource(targetDataSources.get(props.getPrimary()));
routing.setTargetDataSources(targetDataSources);
return routing;
}
}

View File

@@ -0,0 +1,18 @@
package com.xiang.xservice.mysql.config;
public class DynamicDataSourceContext {
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();
public static void set(String datasource) {
CONTEXT.set(datasource);
}
public static String get() {
return CONTEXT.get();
}
public static void clear() {
CONTEXT.remove();
}
}

View File

@@ -0,0 +1,16 @@
package com.xiang.xservice.mysql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DataSourceProperty {
private String url;
private String username;
private String password;
private String driverClassName = "com.mysql.cj.jdbc.Driver";
}

View File

@@ -0,0 +1,18 @@
package com.xiang.xservice.mysql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.HashMap;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource")
public class DynamicDataSourceProperties {
private String primary;
private Map<String, DataSourceProperty> datasource = new HashMap<>();
}

View File

@@ -0,0 +1,11 @@
package com.xiang.xservice.mysql.service;
import com.xiang.xservice.mysql.config.DynamicDataSourceContext;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContext.get();
}
}

View File

@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xiang.xservice.mysql.config.DynamicDataSourceConfig