提交 ef37762d 编写于 作者: 小傅哥's avatar 小傅哥

小傅哥,数据库路由组件设计

上级 2a74bb1f
......@@ -21,3 +21,4 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/db-router-spring-boot-starter.iml
<?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>
<groupId>cn.bugstack.middleware</groupId>
<artifactId>db-router-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>db-router-spring-boot-starter</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package cn.bugstack.middleware.db.router.config;
import cn.bugstack.middleware.db.router.dynamic.DynamicDataSource;
import cn.bugstack.middleware.db.router.util.PropertyUtil;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Configuration
public class DataSourceAutoConfig implements EnvironmentAware {
@Bean
public DataSource dataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("db01", new DriverManagerDataSource("jdbc:mysql://127.0.0.1:3306/bugstack?useUnicode=true", "root", "1234"));
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(targetDataSources);
return dynamicDataSource;
}
@Override
public void setEnvironment(Environment environment) {
String prefix = "router.jdbc.datasource.";
String dataSources = environment.getProperty(prefix + "list");
assert dataSources != null;
for (String each : dataSources.split(",")) {
Map<String, Object> dataSourceProps = PropertyUtil.handle(environment, prefix + each, Map.class);
}
}
}
package cn.bugstack.middleware.db.router.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DataSourceProperties {
public static final String PREFIX = "spring.datasource";
private String username;
private String password;
private String url;
private String driverClassName;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
}
package cn.bugstack.middleware.db.router.dynamic;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return "db01";
}
}
package cn.bugstack.middleware.db.router.util;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DataSourceUtil {
}
package cn.bugstack.middleware.db.router.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertyResolver;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class PropertyUtil {
private static int springBootVersion = 1;
static {
try {
Class.forName("org.springframework.boot.bind.RelaxedPropertyResolver");
} catch (ClassNotFoundException e) {
springBootVersion = 2;
}
}
/**
* Spring Boot 1.x is compatible with Spring Boot 2.x by Using Java Reflect.
* @param environment : the environment context
* @param prefix : the prefix part of property key
* @param targetClass : the target class type of result
* @param <T> : refer to @param targetClass
* @return T
*/
@SuppressWarnings("unchecked")
public static <T> T handle(final Environment environment, final String prefix, final Class<T> targetClass) {
switch (springBootVersion) {
case 1:
return (T) v1(environment, prefix);
default:
return (T) v2(environment, prefix, targetClass);
}
}
private static Object v1(final Environment environment, final String prefix) {
try {
Class<?> resolverClass = Class.forName("org.springframework.boot.bind.RelaxedPropertyResolver");
Constructor<?> resolverConstructor = resolverClass.getDeclaredConstructor(PropertyResolver.class);
Method getSubPropertiesMethod = resolverClass.getDeclaredMethod("getSubProperties", String.class);
Object resolverObject = resolverConstructor.newInstance(environment);
String prefixParam = prefix.endsWith(".") ? prefix : prefix + ".";
return getSubPropertiesMethod.invoke(resolverObject, prefixParam);
} catch (final ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
| IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
private static Object v2(final Environment environment, final String prefix, final Class<?> targetClass) {
try {
Class<?> binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder");
Method getMethod = binderClass.getDeclaredMethod("get", Environment.class);
Method bindMethod = binderClass.getDeclaredMethod("bind", String.class, Class.class);
Object binderObject = getMethod.invoke(null, environment);
String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix;
Object bindResultObject = bindMethod.invoke(binderObject, prefixParam, targetClass);
Method resultGetMethod = bindResultObject.getClass().getDeclaredMethod("get");
return resultGetMethod.invoke(bindResultObject);
} catch (final ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.bugstack.middleware.db.router.config.DataSourceAutoConfig
\ No newline at end of file
package cn.bugstack.middleware.test;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class ApiTest {
public static void main(String[] args) {
System.out.println("Hi");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册