更新sql和代码规范修改

This commit is contained in:
moxiangrong
2024-02-18 15:26:45 +08:00
parent 6f5e6e4662
commit c132b68745
1293 changed files with 43935 additions and 18456 deletions

View File

@ -27,14 +27,14 @@ public class TenantProperties {
/**
* 需要忽略多租户的请求
*
* <p>
* 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API
*/
private Set<String> ignoreUrls = Collections.emptySet();
/**
* 需要忽略多租户的表
*
* <p>
* 即默认所有表都开启多租户的功能,所以记得添加对应的 tenant_id 字段哟
*/
private Set<String> ignoreTables = Collections.emptySet();

View File

@ -36,7 +36,8 @@ import org.springframework.data.redis.core.RedisTemplate;
import java.util.Objects;
@AutoConfiguration
@ConditionalOnProperty(prefix = "yshop.tenant", value = "enable", matchIfMissing = true) // 允许使用 yshop.tenant.enable=false 禁用多租户
@ConditionalOnProperty(prefix = "yshop.tenant", value = "enable", matchIfMissing = true)
// 允许使用 yshop.tenant.enable=false 禁用多租户
@EnableConfigurationProperties(TenantProperties.class)
public class YshopTenantAutoConfiguration {

View File

@ -4,7 +4,7 @@ import java.lang.annotation.*;
/**
* 忽略租户,标记指定方法不进行租户的自动过滤
*
* <p>
* 注意,只有 DB 的场景会过滤,其它场景暂时不过滤:
* 1、Redis 场景:因为是基于 Key 实现多租户的能力,所以忽略没有意义,不像 DB 是一个 column 实现的
* 2、MQ 场景:有点难以抉择,目前可以通过 Consumer 手动在消费的方法上,添加 @TenantIgnore 进行忽略

View File

@ -11,7 +11,7 @@ import org.aspectj.lang.annotation.Aspect;
* 忽略多租户的 Aspect基于 {@link TenantIgnore} 注解实现,用于一些全局的逻辑。
* 例如说,一个定时任务,读取所有数据,进行处理。
* 又例如说,读取所有数据,进行缓存。
*
* <p>
* 整体逻辑的实现,和 {@link TenantUtils#executeIgnore(Runnable)} 需要保持一致
*
* @author yshop

View File

@ -38,7 +38,7 @@ public class TenantContextHolder {
Long tenantId = getTenantId();
if (tenantId == null) {
throw new NullPointerException("TenantContextHolder 不存在租户编号!可参考文档:"
+ DocumentEnum.TENANT.getUrl());
+ DocumentEnum.TENANT.getUrl());
}
return tenantId;
}

View File

@ -37,7 +37,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler {
@Override
public boolean ignoreTable(String tableName) {
return TenantContextHolder.isIgnore() // 情况一,全局忽略多租户
|| CollUtil.contains(ignoreTables, tableName); // 情况二,忽略多租户的表
|| CollUtil.contains(ignoreTables, tableName); // 情况二,忽略多租户的表
}
}

View File

@ -14,7 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* 多租户 JobHandler 装饰器
* 任务执行时,会按照租户逐个执行 Job 的逻辑
*
* <p>
* 注意,需要保证 JobHandler 的幂等性。因为 Job 因为某个租户执行失败重试时,之前执行成功的租户也会再次执行。
*
* @author yshop

View File

@ -9,7 +9,7 @@ import static co.yixiang.yshop.framework.web.core.util.WebFrameworkUtils.HEADER_
/**
* 多租户 {@link AbstractRedisMessage} 拦截器
*
* <p>
* 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中
* 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中
*

View File

@ -9,7 +9,7 @@ import org.springframework.data.redis.cache.RedisCacheWriter;
/**
* 多租户的 {@link RedisCacheManager} 实现类
*
* <p>
* 操作指定 name 的 {@link Cache} 时,自动拼接租户后缀,格式为 name + ":" + tenantId + 后缀
*
* @author airhead
@ -26,7 +26,7 @@ public class TenantRedisCacheManager extends RedisCacheManager {
public Cache getCache(String name) {
// 如果开启多租户,则 name 拼接租户后缀
if (!TenantContextHolder.isIgnore()
&& TenantContextHolder.getTenantId() != null) {
&& TenantContextHolder.getTenantId() != null) {
name = name + ":" + TenantContextHolder.getTenantId();
}

View File

@ -8,12 +8,12 @@ import java.time.Duration;
/**
* 多租户拓展的 RedisKeyDefine 实现类
*
* <p>
* 由于 Redis 不同于 MySQL 有 column 字段,无法通过类似 WHERE tenant_id = ? 的方式过滤
* 所以需要通过在 Redis Key 上增加后缀的方式,进行租户之间的隔离。具体的步骤是:
* 1. 假设 Redis Key 是 user:%d示例是 user:1对应到多租户的 Redis Key 是 user:%d:%d
* 2. 在 Redis DAO 中,需要使用 {@link #formatKey(Object...)} 方法,进行 Redis Key 的格式化
*
* <p>
* 注意,大多数情况下,并不用使用 TenantRedisKeyDefine 实现。主要的使用场景,还是 Redis Key 可能存在冲突的情况。
* 例如说,租户 1 和 2 都有一个手机号作为 Key则他们会存在冲突的问题
*

View File

@ -62,7 +62,7 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
if (tenantId == null) {
tenantId = user.getTenantId();
TenantContextHolder.setTenantId(tenantId);
// 如果传递了租户编号,则进行比对租户编号,避免越权问题
// 如果传递了租户编号,则进行比对租户编号,避免越权问题
} else if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) {
log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]",
user.getTenantId(), user.getId(), user.getUserType(),

View File

@ -16,7 +16,7 @@ public class TenantUtils {
/**
* 使用指定租户,执行对应的逻辑
*
* <p>
* 注意,如果当前是忽略租户的情况下,会被强制设置成不忽略租户
* 当然,执行完成后,还是会恢复回去
*
@ -39,7 +39,7 @@ public class TenantUtils {
/**
* 使用指定租户,执行对应的逻辑
*
* <p>
* 注意,如果当前是忽略租户的情况下,会被强制设置成不忽略租户
* 当然,执行完成后,还是会恢复回去
*

View File

@ -7,11 +7,10 @@
* 5. Job在 JobHandler 执行任务时,会按照每个租户,都独立并行执行一次。
* 6. MQ在 Producer 发送消息时Header 带上 tenant-id 租户编号;在 Consumer 消费消息时,将 Header 的 tenant-id 租户编号,添加到租户上下文。
* 7. Async异步需要保证 ThreadLocal 的传递性,通过使用阿里开源的 TransmittableThreadLocal 实现。相关的改造点,可见:
* 1Spring Async
* {@link co.yixiang.yshop.framework.quartz.config.YshopAsyncAutoConfiguration#threadPoolTaskExecutorBeanPostProcessor()}
* 2Spring Security
* TransmittableThreadLocalSecurityContextHolderStrategy
* 和 YshopSecurityAutoConfiguration#securityContextHolderMethodInvokingFactoryBean() 方法
*
* 1Spring Async
* {@link co.yixiang.yshop.framework.quartz.config.YshopAsyncAutoConfiguration#threadPoolTaskExecutorBeanPostProcessor()}
* 2Spring Security
* TransmittableThreadLocalSecurityContextHolderStrategy
* 和 YshopSecurityAutoConfiguration#securityContextHolderMethodInvokingFactoryBean() 方法
*/
package co.yixiang.yshop.framework.tenant;