Skip to content

Commit

Permalink
refactor(extension/tenant): 多租户组件适配动态隔离级别 (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
xtanyu authored Dec 20, 2024
1 parent 7c3f15a commit c089df6
Show file tree
Hide file tree
Showing 20 changed files with 299 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

package top.continew.starter.extension.tenant.autoconfigure;

import cn.hutool.core.convert.Convert;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.HandlerInterceptor;
import top.continew.starter.extension.tenant.context.TenantContext;
import top.continew.starter.extension.tenant.config.TenantProvider;
import top.continew.starter.extension.tenant.context.TenantContextHolder;

/**
Expand All @@ -29,20 +29,25 @@
* @author Charles7c
* @since 2.7.0
*/
public class TenantInterceptor implements HandlerInterceptor {
public class TenantInterceptor implements HandlerInterceptor, Ordered {

private final TenantProperties tenantProperties;
private final TenantProvider tenantProvider;

public TenantInterceptor(TenantProperties tenantProperties) {
public TenantInterceptor(TenantProperties tenantProperties, TenantProvider tenantProvider) {
this.tenantProperties = tenantProperties;
this.tenantProvider = tenantProvider;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String tenantId = request.getHeader(tenantProperties.getTenantIdHeader());
TenantContext tenantContext = new TenantContext();
tenantContext.setTenantId(Convert.toLong(tenantId));
TenantContextHolder.setContext(tenantContext);
TenantContextHolder.setContext(tenantProvider.getByTenantId(tenantId, true));
return true;
}

@Override
public int getOrder() {
return Integer.MIN_VALUE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import org.springframework.boot.context.properties.ConfigurationProperties;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.extension.tenant.enums.TenantIsolationLevel;

import java.util.List;

Expand All @@ -36,11 +35,6 @@ public class TenantProperties {
*/
private boolean enabled = true;

/**
* 租户隔离级别
*/
private TenantIsolationLevel isolationLevel = TenantIsolationLevel.LINE;

/**
* 租户 ID 列名
*/
Expand Down Expand Up @@ -69,14 +63,6 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public TenantIsolationLevel getIsolationLevel() {
return isolationLevel;
}

public void setIsolationLevel(TenantIsolationLevel isolationLevel) {
this.isolationLevel = isolationLevel;
}

public String getTenantIdColumn() {
return tenantIdColumn;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.extension.tenant.config.TenantProvider;

/**
* 多租户 Web MVC 自动配置
Expand All @@ -35,13 +36,15 @@
public class TenantWebMvcAutoConfiguration implements WebMvcConfigurer {

private final TenantProperties tenantProperties;
private final TenantProvider tenantProvider;

public TenantWebMvcAutoConfiguration(TenantProperties tenantProperties) {
public TenantWebMvcAutoConfiguration(TenantProperties tenantProperties, TenantProvider tenantProvider) {
this.tenantProperties = tenantProperties;
this.tenantProvider = tenantProvider;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TenantInterceptor(tenantProperties));
registry.addInterceptor(new TenantInterceptor(tenantProperties, tenantProvider));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@

package top.continew.starter.extension.tenant.config;

import top.continew.starter.extension.tenant.context.TenantContext;

/**
* 租户数据源提供者
* 租户数据提供者
*
* @author Charles7c
* @since 2.7.0
*/
public interface TenantDataSourceProvider {
public interface TenantProvider {

/**
* 根据租户 ID 获取数据源配置
* 根据租户ID获取租户数据
*
* @param tenantId 租户 ID
* @param verify 是否验证租户有效性
* @return 数据源配置
*/
TenantDataSource getByTenantId(String tenantId);
TenantContext getByTenantId(String tenantId, boolean verify);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package top.continew.starter.extension.tenant.context;

import top.continew.starter.extension.tenant.config.TenantDataSource;
import top.continew.starter.extension.tenant.enums.TenantIsolationLevel;

/**
* 租户上下文
*
Expand All @@ -29,11 +32,37 @@ public class TenantContext {
*/
private Long tenantId;

/**
* 隔离级别
*/
private TenantIsolationLevel isolationLevel;

/**
* 数据源信息
*/
private TenantDataSource dataSource;

public Long getTenantId() {
return tenantId;
}

public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}

public TenantIsolationLevel getIsolationLevel() {
return isolationLevel;
}

public void setIsolationLevel(TenantIsolationLevel isolationLevel) {
this.isolationLevel = isolationLevel;
}

public TenantDataSource getDataSource() {
return dataSource;
}

public void setDataSource(TenantDataSource dataSource) {
this.dataSource = dataSource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package top.continew.starter.extension.tenant.context;

import com.alibaba.ttl.TransmittableThreadLocal;
import top.continew.starter.extension.tenant.enums.TenantIsolationLevel;

import java.util.Optional;

Expand Down Expand Up @@ -66,4 +67,13 @@ public static void clearContext() {
public static Long getTenantId() {
return Optional.ofNullable(getContext()).map(TenantContext::getTenantId).orElse(null);
}

/**
* 获取隔离级别
*/
public static TenantIsolationLevel getIsolationLevel() {
return Optional.ofNullable(getContext())
.map(TenantContext::getIsolationLevel)
.orElse(TenantIsolationLevel.LINE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ public interface TenantDataSourceHandler {
/**
* 切换数据源
*
* @param dataSourceName 数据源名称
*/
void changeDataSource(String dataSourceName);
void changeDataSource(TenantDataSource tenantDataSource);

/**
* 是否存在指定数据源
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package top.continew.starter.extension.tenant.handler;

/**
* @description: 租户处理器
* @author: 小熊
* @create: 2024-12-18 19:37
*/
public interface TenantHandler {

/**
* 在指定租户中执行方法
*/
void executeInTenant(Long tenantId, Runnable runnable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
<optional>true</optional>
</dependency>

<!-- 核心模块 -->
Expand Down
Loading

0 comments on commit c089df6

Please sign in to comment.