diff --git a/pom.xml b/pom.xml
index f82caa9..ff07845 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,7 @@
ym-websocket
ym-packing
ym-s7
+ ym-dynamic-datasource
pom
@@ -241,4 +242,4 @@
-
\ No newline at end of file
+
diff --git a/ym-dynamic-datasource/pom.xml b/ym-dynamic-datasource/pom.xml
new file mode 100644
index 0000000..0ee5918
--- /dev/null
+++ b/ym-dynamic-datasource/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ ym-pass
+ com.cnbm
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ ym-dynamic-datasource
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+ ${project.artifactId}
+
+
+
+
\ No newline at end of file
diff --git a/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/annotation/DataSource.java b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/annotation/DataSource.java
new file mode 100644
index 0000000..8adef9a
--- /dev/null
+++ b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/annotation/DataSource.java
@@ -0,0 +1,11 @@
+package com.cnbm.dynamic.datasource.annotation;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface DataSource {
+ String value() default "";
+}
diff --git a/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/aspect/DataSourceAspect.java b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/aspect/DataSourceAspect.java
new file mode 100644
index 0000000..9534233
--- /dev/null
+++ b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/aspect/DataSourceAspect.java
@@ -0,0 +1,57 @@
+package com.cnbm.dynamic.datasource.aspect;
+
+import com.cnbm.dynamic.datasource.annotation.DataSource;
+import com.cnbm.dynamic.datasource.config.DynamicContextHolder;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+@Aspect
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class DataSourceAspect {
+ protected Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Pointcut("@annotation(com.cnbm.dynamic.datasource.annotation.DataSource) " +
+ "|| @within(com.cnbm.dynamic.datasource.annotation.DataSource)")
+ public void dataSourcePointCut() {
+
+ }
+
+ @Around("dataSourcePointCut()")
+ public Object around(ProceedingJoinPoint point) throws Throwable {
+ MethodSignature signature = (MethodSignature) point.getSignature();
+ Class targetClass = point.getTarget().getClass();
+ Method method = signature.getMethod();
+
+ DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
+ DataSource methodDataSource = method.getAnnotation(DataSource.class);
+ if(targetDataSource != null || methodDataSource != null){
+ String value;
+ if(methodDataSource != null){
+ value = methodDataSource.value();
+ }else {
+ value = targetDataSource.value();
+ }
+
+ DynamicContextHolder.push(value);
+ logger.debug("set datasource is {}", value);
+ }
+
+ try {
+ return point.proceed();
+ } finally {
+ DynamicContextHolder.poll();
+ logger.debug("clean datasource");
+ }
+ }
+}
diff --git a/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicContextHolder.java b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicContextHolder.java
new file mode 100644
index 0000000..b3b2ca5
--- /dev/null
+++ b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicContextHolder.java
@@ -0,0 +1,44 @@
+package com.cnbm.dynamic.datasource.config;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+public class DynamicContextHolder {
+ @SuppressWarnings("unchecked")
+ private static final ThreadLocal> CONTEXT_HOLDER = new ThreadLocal() {
+ @Override
+ protected Object initialValue() {
+ return new ArrayDeque();
+ }
+ };
+
+ /**
+ * 获得当前线程数据源
+ *
+ * @return 数据源名称
+ */
+ public static String peek() {
+ return CONTEXT_HOLDER.get().peek();
+ }
+
+ /**
+ * 设置当前线程数据源
+ *
+ * @param dataSource 数据源名称
+ */
+ public static void push(String dataSource) {
+ CONTEXT_HOLDER.get().push(dataSource);
+ }
+
+ /**
+ * 清空当前线程数据源
+ */
+ public static void poll() {
+ Deque deque = CONTEXT_HOLDER.get();
+ deque.poll();
+ if (deque.isEmpty()) {
+ CONTEXT_HOLDER.remove();
+ }
+ }
+
+}
diff --git a/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicDataSource.java b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicDataSource.java
new file mode 100644
index 0000000..ee30a34
--- /dev/null
+++ b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicDataSource.java
@@ -0,0 +1,12 @@
+package com.cnbm.dynamic.datasource.config;
+
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+public class DynamicDataSource extends AbstractRoutingDataSource {
+
+ @Override
+ protected Object determineCurrentLookupKey() {
+ return DynamicContextHolder.peek();
+ }
+
+}
diff --git a/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicDataSourceConfig.java b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicDataSourceConfig.java
new file mode 100644
index 0000000..4e55ef6
--- /dev/null
+++ b/ym-dynamic-datasource/src/main/java/com/cnbm/dynamic/datasource/config/DynamicDataSourceConfig.java
@@ -0,0 +1,50 @@
+package com.cnbm.dynamic.datasource.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.cnbm.dynamic.datasource.properties.DataSourceProperties;
+import com.cnbm.dynamic.datasource.properties.DynamicDataSourceProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@EnableConfigurationProperties(DynamicDataSourceProperties.class)
+public class DynamicDataSourceConfig {
+ @Autowired
+ private DynamicDataSourceProperties properties;
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource")
+ public DataSourceProperties dataSourceProperties() {
+ return new DataSourceProperties();
+ }
+
+ @Bean
+ public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
+ DynamicDataSource dynamicDataSource = new DynamicDataSource();
+ dynamicDataSource.setTargetDataSources(getDynamicDataSource());
+
+ //默认数据源
+ DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
+ dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
+
+ return dynamicDataSource;
+ }
+
+ private Map