增加了multi-tenant-core, multi-tenant-datasource ,未完全测试
diff --git a/build.gradle b/build.gradle
index c8474f6..cfaf067 100644
--- a/build.gradle
+++ b/build.gradle
@@ -98,6 +98,7 @@
             jerseyClientVersion = '1.19'
             javaxWSRSVersion = '2.1.1'
             dom4jVersion = '2.1.1'
+            javaxServletVersion = '4.0.1'
             springSocialVersion = '1.1.6.RELEASE'
             springKafkaVersion = '2.2.8.RELEASE'
             postgresVersion = '42.2.5'
@@ -135,10 +136,14 @@
 //        testImplementation 'org.springframework.boot:spring-boot-test'
 //    implementation "javax.servlet:jstl:1.2"
 //    implementation "taglibs:standard:1.1.2"
-        testImplementation "org.springframework.boot:spring-boot-starter-test"
+
+        testImplementation("org.springframework.boot:spring-boot-starter-test") {
+            exclude group: "junit", module: "junit"
+        }
         testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}"
         testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}"
         testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
+        testRuntimeOnly("org.junit.vintage:junit-vintage-engine:${junit_jupiter_version}")
         testImplementation "io.mockk:mockk:${mockkVersion}"
         testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
         testImplementation "io.rest-assured:rest-assured:${resetAssuredVersion}"
diff --git a/multi-tenant-core/build.gradle b/multi-tenant-core/build.gradle
new file mode 100644
index 0000000..b456c6e
--- /dev/null
+++ b/multi-tenant-core/build.gradle
@@ -0,0 +1,9 @@
+plugins {
+    id 'java'
+    id 'org.springframework.boot'
+}
+
+dependencies {
+    implementation "org.springframework:spring-webmvc"
+    implementation "javax.servlet:javax.servlet-api:${javaxServletVersion}"
+}
\ No newline at end of file
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/MultiTenantAutoConfiguration.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/MultiTenantAutoConfiguration.java
new file mode 100644
index 0000000..3ea1eb1
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/MultiTenantAutoConfiguration.java
@@ -0,0 +1,40 @@
+package com.supwisdom.multitenant;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Role;
+
+public class MultiTenantAutoConfiguration {
+
+  @Configuration
+  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+  @ComponentScan(basePackages = {"com.supwisdom.multitenant"})
+  public static class SessionTenantInterceptorAutoConfig {
+  }
+
+  //  @ConditionalOnProperty(
+//      name = "multi-tenant.interceptor.httpsession.enabled",
+//      havingValue = "true")
+//  @Bean
+//  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+//  @ConditionalOnBean({SessionTenantInterceptorAutoConfig.class})
+//  public SessionTenantInterceptorAutoConfig createSessionInterceptor() {
+//    return new SessionTenantInterceptorAutoConfig();
+//  }
+
+  @Configuration
+  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+  @ComponentScan(basePackages = {"com.supwisdom.multitenant"})
+  public static class HttpHeaderTenantInterceptorAutoConfig {
+  }
+
+//  @Bean
+//  @ConditionalOnProperty(
+//      name = "multi-tenant.interceptor.httpheader.enabled",
+//      havingValue = "true")
+//  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+//  public HttpHeaderTenantInterceptorAutoConfig createHttpHeaderInterceptor() {
+//    return new HttpHeaderTenantInterceptorAutoConfig();
+//  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContext.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContext.java
new file mode 100644
index 0000000..0c3bbf2
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContext.java
@@ -0,0 +1,9 @@
+package com.supwisdom.multitenant;
+
+import java.io.Serializable;
+
+public interface TenantContext extends Serializable {
+  TenantDetails getTenant();
+
+  void setTenant(TenantDetails details);
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolder.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolder.java
new file mode 100644
index 0000000..bb0d51f
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolder.java
@@ -0,0 +1,24 @@
+package com.supwisdom.multitenant;
+
+import com.supwisdom.multitenant.impl.ThreadLocalTenantContextHolderStrategy;
+
+public class TenantContextHolder {
+  private static TenantContextHolderStrategy strategy;
+
+  static {
+    initialize();
+  }
+
+  private static void initialize() {
+    strategy = new ThreadLocalTenantContextHolderStrategy();
+  }
+
+  public static TenantContext getContext() {
+    return strategy.getContext();
+  }
+
+  public static void clearContext() {
+    strategy.clearContext();
+  }
+
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolderStrategy.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolderStrategy.java
new file mode 100644
index 0000000..300130a
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantContextHolderStrategy.java
@@ -0,0 +1,11 @@
+package com.supwisdom.multitenant;
+
+public interface TenantContextHolderStrategy {
+  TenantContext getContext();
+
+  void setContext(TenantContext tenant);
+
+  TenantContext createEmptyContext();
+
+  void clearContext();
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantDetails.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantDetails.java
new file mode 100644
index 0000000..07372bb
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantDetails.java
@@ -0,0 +1,46 @@
+package com.supwisdom.multitenant;
+
+import java.io.Serializable;
+
+public class TenantDetails implements Serializable {
+  private String id;
+
+  private String dbSchema;
+
+  private Boolean enabled;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getDbSchema() {
+    return dbSchema;
+  }
+
+  public void setDbSchema(String dbSchema) {
+    this.dbSchema = dbSchema;
+  }
+
+  public Boolean getEnabled() {
+    return enabled;
+  }
+
+  public void setEnabled(Boolean enabled) {
+    this.enabled = enabled;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof TenantDetails) {
+      TenantDetails other = (TenantDetails) obj;
+      if (getId().equals(other.getId())) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantInterceptor.java
new file mode 100644
index 0000000..3a50249
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/TenantInterceptor.java
@@ -0,0 +1,7 @@
+package com.supwisdom.multitenant;
+
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public abstract class TenantInterceptor extends HandlerInterceptorAdapter {
+
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableHttpHeaderTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableHttpHeaderTenantInterceptor.java
new file mode 100644
index 0000000..97f8625
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableHttpHeaderTenantInterceptor.java
@@ -0,0 +1,13 @@
+package com.supwisdom.multitenant.annotations;
+
+import com.supwisdom.multitenant.MultiTenantAutoConfiguration;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Import(MultiTenantAutoConfiguration.HttpHeaderTenantInterceptorAutoConfig.class)
+@Documented
+public @interface EnableHttpHeaderTenantInterceptor {
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableSessionTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableSessionTenantInterceptor.java
new file mode 100644
index 0000000..885140b
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/annotations/EnableSessionTenantInterceptor.java
@@ -0,0 +1,13 @@
+package com.supwisdom.multitenant.annotations;
+
+import com.supwisdom.multitenant.MultiTenantAutoConfiguration;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Import(MultiTenantAutoConfiguration.SessionTenantInterceptorAutoConfig.class)
+@Documented
+public @interface EnableSessionTenantInterceptor {
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/HttpHeaderWebMvcConfig.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/HttpHeaderWebMvcConfig.java
new file mode 100644
index 0000000..b2d9585
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/HttpHeaderWebMvcConfig.java
@@ -0,0 +1,23 @@
+package com.supwisdom.multitenant.config;
+
+
+import com.supwisdom.multitenant.impl.HttpHeaderTenantInterceptor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+@ConditionalOnBean(value = {HttpHeaderTenantInterceptor.class})
+public class HttpHeaderWebMvcConfig implements WebMvcConfigurer {
+  private final HttpHeaderTenantInterceptor interceptor;
+
+  public HttpHeaderWebMvcConfig(HttpHeaderTenantInterceptor interceptor) {
+    this.interceptor = interceptor;
+  }
+
+  @Override
+  public void addInterceptors(InterceptorRegistry registry) {
+    registry.addInterceptor(interceptor);
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantCoreUtils.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantCoreUtils.java
new file mode 100644
index 0000000..97c7096
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantCoreUtils.java
@@ -0,0 +1,6 @@
+package com.supwisdom.multitenant.config;
+
+public final class TenantCoreUtils {
+  public static final String INTERNAL_TENANT_INTERCEPTOR_BEAN_NAME = "coms.supwisdom.multitenant.interceptor";
+
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantHeaderProperties.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantHeaderProperties.java
new file mode 100644
index 0000000..4d31390
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantHeaderProperties.java
@@ -0,0 +1,20 @@
+package com.supwisdom.multitenant.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties("multi-tenant.header")
+public class TenantHeaderProperties {
+  @Value("${key:X-Tenant-Id}")
+  private String key;
+
+  public String getKey() {
+    return key;
+  }
+
+  public void setKey(String key) {
+    this.key = key;
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantJwtProperties.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantJwtProperties.java
new file mode 100644
index 0000000..c4dcbb4
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantJwtProperties.java
@@ -0,0 +1,31 @@
+package com.supwisdom.multitenant.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties("multi-tenant.jwt")
+public class TenantJwtProperties {
+  @Value("${header:Authentication}")
+  private String jwtHeader;
+
+  @Value("${schema:Bears}")
+  private String schema;
+
+  public String getJwtHeader() {
+    return jwtHeader;
+  }
+
+  public void setJwtHeader(String jwtHeader) {
+    this.jwtHeader = jwtHeader;
+  }
+
+  public String getSchema() {
+    return schema;
+  }
+
+  public void setSchema(String schema) {
+    this.schema = schema;
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantSessionProperties.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantSessionProperties.java
new file mode 100644
index 0000000..3d57c62
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/config/TenantSessionProperties.java
@@ -0,0 +1,20 @@
+package com.supwisdom.multitenant.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties("multi-tenant.session")
+public class TenantSessionProperties {
+  @Value("${name:multi-tenant-id}")
+  private String name;
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/HttpHeaderTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/HttpHeaderTenantInterceptor.java
new file mode 100644
index 0000000..b8ae342
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/HttpHeaderTenantInterceptor.java
@@ -0,0 +1,47 @@
+package com.supwisdom.multitenant.impl;
+
+import com.supwisdom.multitenant.*;
+import com.supwisdom.multitenant.config.TenantHeaderProperties;
+import com.supwisdom.multitenant.config.TenantJwtProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Component
+@ConditionalOnBean(MultiTenantAutoConfiguration.HttpHeaderTenantInterceptorAutoConfig.class)
+public class HttpHeaderTenantInterceptor extends TenantInterceptor {
+  private final TenantJwtProperties properties;
+
+  private final TenantHeaderProperties headerProperties;
+
+  public HttpHeaderTenantInterceptor(TenantJwtProperties properties,
+                                     TenantHeaderProperties headerProperties) {
+    this.properties = properties;
+    this.headerProperties = headerProperties;
+  }
+
+  @Override
+  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+    String tenant = request.getHeader(headerProperties.getKey());
+    if (tenant != null && !StringUtils.isEmpty(tenant)) {
+      TenantDetails details = new TenantDetails();
+      details.setId(tenant);
+      TenantContextHolder.getContext().setTenant(details);
+    }
+    String header = request.getHeader(properties.getJwtHeader());
+    if (header.startsWith(properties.getSchema())) {
+      // parse jwt
+    }
+    return super.preHandle(request, response, handler);
+  }
+
+  @Override
+  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+                         ModelAndView modelAndView) throws Exception {
+    TenantContextHolder.clearContext();
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/SessionTenantInterceptor.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/SessionTenantInterceptor.java
new file mode 100644
index 0000000..3f9ae2c
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/SessionTenantInterceptor.java
@@ -0,0 +1,39 @@
+package com.supwisdom.multitenant.impl;
+
+import com.supwisdom.multitenant.*;
+import com.supwisdom.multitenant.config.TenantSessionProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Component
+@ConditionalOnBean(MultiTenantAutoConfiguration.SessionTenantInterceptorAutoConfig.class)
+public class SessionTenantInterceptor extends TenantInterceptor {
+  private final TenantSessionProperties properties;
+
+  public SessionTenantInterceptor(TenantSessionProperties properties) {
+    this.properties = properties;
+  }
+
+  @Override
+  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+    String tenant = (String) request.getSession().getAttribute(properties.getName());
+    if (tenant != null && !StringUtils.isEmpty(tenant)) {
+      TenantDetails details = new TenantDetails();
+      details.setId(tenant);
+      TenantContextHolder.getContext().setTenant(details);
+    }
+    return super.preHandle(request, response, handler);
+  }
+
+  @Override
+  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+                         ModelAndView modelAndView) throws Exception {
+    TenantContextHolder.clearContext();
+    super.postHandle(request, response, handler, modelAndView);
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/TenantContextImpl.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/TenantContextImpl.java
new file mode 100644
index 0000000..39bdae8
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/TenantContextImpl.java
@@ -0,0 +1,27 @@
+package com.supwisdom.multitenant.impl;
+
+import com.supwisdom.multitenant.TenantContext;
+import com.supwisdom.multitenant.TenantDetails;
+
+public class TenantContextImpl implements TenantContext {
+  private TenantDetails details;
+
+  @Override
+  public TenantDetails getTenant() {
+    return details;
+  }
+
+  @Override
+  public void setTenant(TenantDetails details) {
+    this.details = details;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof TenantContextImpl) {
+      TenantContextImpl other = (TenantContextImpl) obj;
+      getTenant().equals(other.getTenant());
+    }
+    return false;
+  }
+}
diff --git a/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/ThreadLocalTenantContextHolderStrategy.java b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/ThreadLocalTenantContextHolderStrategy.java
new file mode 100644
index 0000000..fd325ec
--- /dev/null
+++ b/multi-tenant-core/src/main/java/com/supwisdom/multitenant/impl/ThreadLocalTenantContextHolderStrategy.java
@@ -0,0 +1,33 @@
+package com.supwisdom.multitenant.impl;
+
+import com.supwisdom.multitenant.TenantContext;
+import com.supwisdom.multitenant.TenantContextHolderStrategy;
+
+public class ThreadLocalTenantContextHolderStrategy implements TenantContextHolderStrategy {
+  private static final ThreadLocal<TenantContext> contextHolder = new ThreadLocal<>();
+
+  @Override
+  public TenantContext getContext() {
+    TenantContext context = contextHolder.get();
+    if (context == null) {
+      context = createEmptyContext();
+      contextHolder.set(context);
+    }
+    return context;
+  }
+
+  @Override
+  public void setContext(TenantContext tenant) {
+    contextHolder.set(tenant);
+  }
+
+  @Override
+  public void clearContext() {
+    contextHolder.remove();
+  }
+
+  @Override
+  public TenantContext createEmptyContext() {
+    return new TenantContextImpl();
+  }
+}
diff --git a/multi-tenant-core/src/test/java/com/supwisdom/multitenant/AutoConfigurationTest.java b/multi-tenant-core/src/test/java/com/supwisdom/multitenant/AutoConfigurationTest.java
new file mode 100644
index 0000000..4286f3c
--- /dev/null
+++ b/multi-tenant-core/src/test/java/com/supwisdom/multitenant/AutoConfigurationTest.java
@@ -0,0 +1,33 @@
+package com.supwisdom.multitenant;
+
+import com.supwisdom.multitenant.annotations.EnableSessionTenantInterceptor;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.TestPropertySource;
+
+import java.util.Arrays;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+
+@SpringBootTest(classes = {AutoConfigurationTest.class})
+@EnableSessionTenantInterceptor
+@TestPropertySource("/test.properties")
+public class AutoConfigurationTest {
+
+  @Autowired
+  private ApplicationContext appContext;
+
+  @Test
+  public void testSessionOk() {
+    String[] beans = appContext.getBeanDefinitionNames();
+    Arrays.sort(beans);
+    for (String bean : beans) {
+      System.out.println(bean);
+    }
+    assertThat(TenantContextHolder.getContext(), notNullValue());
+  }
+
+}
diff --git a/multi-tenant-core/src/test/resources/test.properties b/multi-tenant-core/src/test/resources/test.properties
new file mode 100644
index 0000000..80c6377
--- /dev/null
+++ b/multi-tenant-core/src/test/resources/test.properties
@@ -0,0 +1 @@
+debug=true
\ No newline at end of file
diff --git a/multi-tenant/build.gradle b/multi-tenant-datasource/build.gradle
similarity index 94%
rename from multi-tenant/build.gradle
rename to multi-tenant-datasource/build.gradle
index 031c0a3..09ed014 100644
--- a/multi-tenant/build.gradle
+++ b/multi-tenant-datasource/build.gradle
@@ -17,6 +17,7 @@
 }
 
 dependencies {
+    implementation(":multi-tenant-core")
     implementation "org.springframework.boot:spring-boot-autoconfigure"
     implementation "commons-beanutils:commons-beanutils:${beanutilsVersion}"
     implementation "commons-codec:commons-codec:${codecVersion}"
diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java
similarity index 100%
rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java
rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/DefaultMultiTenantFactory.java
diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java
similarity index 100%
rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java
rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/MultiTenantFactory.java
diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java
similarity index 100%
rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java
rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/TenantContext.java
diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java
similarity index 100%
rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java
rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/beans/TenantProps.java
diff --git a/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java
new file mode 100644
index 0000000..3365265
--- /dev/null
+++ b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/HibernateConfig.java
@@ -0,0 +1,65 @@
+package com.supwisdom.payapi.multitenant.config;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.hibernate.MultiTenancyStrategy;
+import org.hibernate.cfg.Environment;
+import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
+import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.orm.jpa.JpaVendorAdapter;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+
+import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@Slf4j
+public class HibernateConfig {
+
+  private final JpaProperties jpaProperties;
+
+  private final HibernateProperties hibernateProperties;
+
+  public HibernateConfig(@Autowired JpaProperties jpaProperties,
+                         HibernateProperties hibernateProperties) {
+    this.jpaProperties = jpaProperties;
+    this.hibernateProperties = hibernateProperties;
+  }
+
+  @Bean
+  public JpaVendorAdapter getJpaVendorAdapter() {
+    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
+    adapter.setGenerateDdl(true);
+    return adapter;
+  }
+
+  @Bean("entityManagerFactory")
+  public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource,
+                                                                         MultiTenantConnectionProvider multiTenantConnectionProvider,
+                                                                         CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
+    Map<String, Object> properties = new HashMap<>();
+    properties.putAll(hibernateProperties
+        .determineHibernateProperties(jpaProperties.getProperties(),
+            new HibernateSettings()));
+    properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA);
+    properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
+    properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
+
+    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+    em.setDataSource(dataSource);
+    em.setPackagesToScan("com.supwisdom");
+    em.setJpaPropertyMap(properties);
+    em.setJpaVendorAdapter(getJpaVendorAdapter());
+    log.info("setup multi-tenant entityManagerFactor");
+    return em;
+  }
+
+}
diff --git a/multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java b/multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java
similarity index 100%
rename from multi-tenant/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java
rename to multi-tenant-datasource/src/main/java/com/supwisdom/payapi/multitenant/config/MultiTenantAutoConfiguration.java
diff --git a/settings.gradle b/settings.gradle
index 43ea36e..9ec25d1 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -4,5 +4,6 @@
 include 'payapi-common'
 include 'ynrcc-agent'
 include 'oauth'
-include 'multi-tenant'
+include 'multi-tenant-core'
+include 'multi-tenant-datasource'