From c089df66cf226aa8062dc7ac2c82fb0111cfc5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=86=8A?= <50282105+xtanyu@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:44:09 +0800 Subject: [PATCH] =?UTF-8?q?refactor(extension/tenant):=20=E5=A4=9A?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E7=BB=84=E4=BB=B6=E9=80=82=E9=85=8D=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E9=9A=94=E7=A6=BB=E7=BA=A7=E5=88=AB=20(#8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autoconfigure/TenantInterceptor.java | 19 ++- .../autoconfigure/TenantProperties.java | 14 -- .../TenantWebMvcAutoConfiguration.java | 7 +- ...ourceProvider.java => TenantProvider.java} | 11 +- .../tenant/context/TenantContext.java | 29 ++++ .../tenant/context/TenantContextHolder.java | 10 ++ .../handler/TenantDataSourceHandler.java | 3 +- .../tenant/handler/TenantHandler.java | 31 +++++ .../pom.xml | 1 - .../TenantAutoConfiguration.java | 129 ++++++++---------- .../DefaultTenantDataSourceHandler.java | 26 ++-- .../tenant/handler/DefaultTenantHandler.java | 73 ++++++++++ .../handler/DefaultTenantLineHandler.java | 4 +- .../handler/TenantDataSourceAdvisor.java | 2 +- .../handler/TenantDataSourceInterceptor.java | 28 ++-- .../log/aop/aspect/ConsoleLogAspect.java | 26 +++- .../starter/log/aop/aspect/LogAspect.java | 27 +++- .../autoconfigure/LogAutoConfiguration.java | 2 +- .../log/aop/autoconfigure/LogProperties.java | 1 - .../starter/log/core/model/LogRecord.java | 1 + 20 files changed, 299 insertions(+), 145 deletions(-) rename continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/{TenantDataSourceProvider.java => TenantProvider.java} (74%) create mode 100644 continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantHandler.java create mode 100644 continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantHandler.java diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantInterceptor.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantInterceptor.java index 53c5849..c0e85aa 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantInterceptor.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantInterceptor.java @@ -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; /** @@ -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; + } } \ No newline at end of file diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantProperties.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantProperties.java index 2f29145..cf0cad1 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantProperties.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantProperties.java @@ -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; @@ -36,11 +35,6 @@ public class TenantProperties { */ private boolean enabled = true; - /** - * 租户隔离级别 - */ - private TenantIsolationLevel isolationLevel = TenantIsolationLevel.LINE; - /** * 租户 ID 列名 */ @@ -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; } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantWebMvcAutoConfiguration.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantWebMvcAutoConfiguration.java index 27baf8f..c9ba228 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantWebMvcAutoConfiguration.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantWebMvcAutoConfiguration.java @@ -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 自动配置 @@ -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)); } } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/TenantDataSourceProvider.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/TenantProvider.java similarity index 74% rename from continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/TenantDataSourceProvider.java rename to continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/TenantProvider.java index 006af20..9856fd1 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/TenantDataSourceProvider.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/config/TenantProvider.java @@ -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); } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContext.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContext.java index 8972d0c..1f05a06 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContext.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContext.java @@ -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; + /** * 租户上下文 * @@ -29,6 +32,16 @@ public class TenantContext { */ private Long tenantId; + /** + * 隔离级别 + */ + private TenantIsolationLevel isolationLevel; + + /** + * 数据源信息 + */ + private TenantDataSource dataSource; + public Long getTenantId() { return tenantId; } @@ -36,4 +49,20 @@ public Long getTenantId() { 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; + } } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContextHolder.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContextHolder.java index fab398f..c7261bd 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContextHolder.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/context/TenantContextHolder.java @@ -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; @@ -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); + } } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceHandler.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceHandler.java index 846cc3a..1b5cb2c 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceHandler.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceHandler.java @@ -31,9 +31,8 @@ public interface TenantDataSourceHandler { /** * 切换数据源 * - * @param dataSourceName 数据源名称 */ - void changeDataSource(String dataSourceName); + void changeDataSource(TenantDataSource tenantDataSource); /** * 是否存在指定数据源 diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantHandler.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantHandler.java new file mode 100644 index 0000000..d9a4f82 --- /dev/null +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-core/src/main/java/top/continew/starter/extension/tenant/handler/TenantHandler.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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); + +} diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/pom.xml b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/pom.xml index a55f452..a09b289 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/pom.xml +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/pom.xml @@ -23,7 +23,6 @@ com.baomidou dynamic-datasource-spring-boot3-starter - true diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantAutoConfiguration.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantAutoConfiguration.java index 2341570..35015f2 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantAutoConfiguration.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/autoconfigure/TenantAutoConfiguration.java @@ -30,7 +30,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.core.ResolvableType; import top.continew.starter.core.constant.PropertiesConstants; -import top.continew.starter.extension.tenant.config.TenantDataSourceProvider; +import top.continew.starter.extension.tenant.config.TenantProvider; import top.continew.starter.extension.tenant.handler.*; /** @@ -49,85 +49,76 @@ public class TenantAutoConfiguration { private TenantAutoConfiguration() { } + static { + log.debug("[ContiNew Starter] - Auto Configuration 'Tenant' completed initialization."); + } + /** - * 租户隔离级别:行级 + * 租户行级隔离拦截器 */ - @AutoConfiguration - @ConditionalOnProperty(name = PropertiesConstants.TENANT + ".isolation-level", havingValue = "line", matchIfMissing = true) - public static class Line { - static { - log.debug("[ContiNew Starter] - Auto Configuration 'Tenant-Line' completed initialization."); - } - - /** - * 租户行级隔离拦截器 - */ - @Bean - @ConditionalOnMissingBean - public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantLineHandler tenantLineHandler) { - return new TenantLineInnerInterceptor(tenantLineHandler); - } + @Bean + @ConditionalOnMissingBean + public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantLineHandler tenantLineHandler) { + return new TenantLineInnerInterceptor(tenantLineHandler); + } - /** - * 租户行级隔离处理器(默认) - */ - @Bean - @ConditionalOnMissingBean - public TenantLineHandler tenantLineHandler(TenantProperties properties) { - return new DefaultTenantLineHandler(properties); - } + /** + * 租户行级隔离处理器(默认) + */ + @Bean + @ConditionalOnMissingBean + public TenantLineHandler tenantLineHandler(TenantProperties properties) { + return new DefaultTenantLineHandler(properties); } /** - * 租户隔离级别:数据源级 + * 租户数据源级隔离通知 */ - @AutoConfiguration - @ConditionalOnProperty(name = PropertiesConstants.TENANT + ".isolation-level", havingValue = "datasource") - public static class DataSource { - static { - log.debug("[ContiNew Starter] - Auto Configuration 'Tenant-DataSource' completed initialization."); - } + @Bean + @ConditionalOnMissingBean + public TenantDataSourceAdvisor tenantDataSourceAdvisor(TenantDataSourceInterceptor tenantDataSourceInterceptor) { + return new TenantDataSourceAdvisor(tenantDataSourceInterceptor); + } - /** - * 租户数据源级隔离通知 - */ - @Bean - @ConditionalOnMissingBean - public TenantDataSourceAdvisor tenantDataSourceAdvisor(TenantDataSourceInterceptor tenantDataSourceInterceptor) { - return new TenantDataSourceAdvisor(tenantDataSourceInterceptor); - } + /** + * 租户数据源级隔离拦截器 + */ + @Bean + @ConditionalOnMissingBean + public TenantDataSourceInterceptor tenantDataSourceInterceptor(TenantDataSourceHandler tenantDataSourceHandler) { + return new TenantDataSourceInterceptor(tenantDataSourceHandler); + } - /** - * 租户数据源级隔离拦截器 - */ - @Bean - @ConditionalOnMissingBean - public TenantDataSourceInterceptor tenantDataSourceInterceptor(TenantDataSourceHandler tenantDataSourceHandler) { - return new TenantDataSourceInterceptor(tenantDataSourceHandler); - } + /** + * 租户数据源级隔离处理器(默认) + */ + @Bean + @ConditionalOnMissingBean + public TenantDataSourceHandler tenantDataSourceHandler(javax.sql.DataSource dataSource, + DefaultDataSourceCreator dataSourceCreator) { + return new DefaultTenantDataSourceHandler((DynamicRoutingDataSource)dataSource, dataSourceCreator); + } - /** - * 租户数据源级隔离处理器(默认) - */ - @Bean - @ConditionalOnMissingBean - public TenantDataSourceHandler tenantDataSourceHandler(TenantDataSourceProvider tenantDataSourceProvider, - DynamicRoutingDataSource dynamicRoutingDataSource, - DefaultDataSourceCreator dataSourceCreator) { - return new DefaultTenantDataSourceHandler(tenantDataSourceProvider, dynamicRoutingDataSource, dataSourceCreator); + /** + * 多租户数据源提供者 + */ + @Bean + @ConditionalOnMissingBean + public TenantProvider tenantDataSourceProvider() { + if (log.isErrorEnabled()) { + log.error("Consider defining a bean of type '{}' in your configuration.", ResolvableType + .forClass(TenantProvider.class)); } + throw new NoSuchBeanDefinitionException(TenantProvider.class); + } - /** - * 多租户数据源提供者 - */ - @Bean - @ConditionalOnMissingBean - public TenantDataSourceProvider tenantDataSourceProvider() { - if (log.isErrorEnabled()) { - log.error("Consider defining a bean of type '{}' in your configuration.", ResolvableType - .forClass(TenantDataSourceProvider.class)); - } - throw new NoSuchBeanDefinitionException(TenantDataSourceProvider.class); - } + /** + * 租户处理器 + */ + @Bean + @ConditionalOnMissingBean + public TenantHandler tenantHandler(TenantDataSourceHandler tenantDataSourceHandler, TenantProvider tenantProvider) { + return new DefaultTenantHandler(tenantDataSourceHandler, tenantProvider); } + } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantDataSourceHandler.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantDataSourceHandler.java index e12d845..0bbde05 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantDataSourceHandler.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantDataSourceHandler.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import top.continew.starter.extension.tenant.config.TenantDataSource; -import top.continew.starter.extension.tenant.config.TenantDataSourceProvider; import javax.sql.DataSource; @@ -39,30 +38,25 @@ public class DefaultTenantDataSourceHandler implements TenantDataSourceHandler { private static final Logger log = LoggerFactory.getLogger(DefaultTenantDataSourceHandler.class); private final DynamicRoutingDataSource dynamicRoutingDataSource; private final DefaultDataSourceCreator dataSourceCreator; - private final TenantDataSourceProvider tenantDataSourceProvider; - public DefaultTenantDataSourceHandler(TenantDataSourceProvider tenantDataSourceProvider, - DynamicRoutingDataSource dynamicRoutingDataSource, + public DefaultTenantDataSourceHandler(DynamicRoutingDataSource dynamicRoutingDataSource, DefaultDataSourceCreator dataSourceCreator) { - this.tenantDataSourceProvider = tenantDataSourceProvider; this.dynamicRoutingDataSource = dynamicRoutingDataSource; this.dataSourceCreator = dataSourceCreator; } @Override - public void changeDataSource(String dataSourceName) { - if (!this.containsDataSource(dataSourceName)) { - TenantDataSource tenantDataSource = tenantDataSourceProvider.getByTenantId(dataSourceName); - if (null == tenantDataSource) { - throw new IllegalArgumentException("Data source [%s] configuration not found" - .formatted(dataSourceName)); + public void changeDataSource(TenantDataSource tenantDataSource) { + if (tenantDataSource != null) { + String dataSourceName = tenantDataSource.getPoolName(); + if (!this.containsDataSource(dataSourceName)) { + DataSource datasource = this.createDataSource(tenantDataSource); + dynamicRoutingDataSource.addDataSource(dataSourceName, datasource); + log.info("Load data source: {}", dataSourceName); } - DataSource datasource = this.createDataSource(tenantDataSource); - dynamicRoutingDataSource.addDataSource(dataSourceName, datasource); - log.info("Load data source: {}", dataSourceName); + DynamicDataSourceContextHolder.push(dataSourceName); + log.info("Change data source: {}", dataSourceName); } - DynamicDataSourceContextHolder.push(dataSourceName); - log.info("Change data source: {}", dataSourceName); } @Override diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantHandler.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantHandler.java new file mode 100644 index 0000000..3be2de4 --- /dev/null +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantHandler.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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; + +import cn.hutool.extra.spring.SpringUtil; +import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; +import top.continew.starter.extension.tenant.config.TenantProvider; +import top.continew.starter.extension.tenant.context.TenantContext; +import top.continew.starter.extension.tenant.context.TenantContextHolder; +import top.continew.starter.extension.tenant.enums.TenantIsolationLevel; + +/** + * @description: 租户处理器 + * @author: 小熊 + * @create: 2024-12-18 19:43 + */ +public class DefaultTenantHandler implements TenantHandler { + + private final TenantDataSourceHandler dataSourceHandler; + private final TenantProvider tenantProvider; + + public DefaultTenantHandler(TenantDataSourceHandler dataSourceHandler, TenantProvider tenantProvider) { + this.dataSourceHandler = dataSourceHandler; + this.tenantProvider = tenantProvider; + } + + @Override + public void executeInTenant(Long tenantId, Runnable runnable) { + boolean enabled = SpringUtil.getProperty("continew-starter.tenant.enabled", Boolean.class, false); + if (enabled) { + TenantContext tenantHandler = tenantProvider.getByTenantId(tenantId.toString(), false); + // 保存当前的租户上下文 + TenantContext originalContext = TenantContextHolder.getContext(); + // 切换数据源 + boolean isPush = false; + try { + // 设置新的租户上下文 + TenantContextHolder.setContext(tenantHandler); + if (TenantIsolationLevel.DATASOURCE.equals(tenantHandler.getIsolationLevel())) { + //切换数据源 + dataSourceHandler.changeDataSource(tenantHandler.getDataSource()); + isPush = true; + } + runnable.run(); + } finally { + // 恢复原始的租户上下文 + if (originalContext != null) { + TenantContextHolder.setContext(originalContext); + } else { + TenantContextHolder.clearContext(); + } + if (isPush) { + DynamicDataSourceContextHolder.poll(); + } + } + } + } + +} diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantLineHandler.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantLineHandler.java index bea84cb..2f273b8 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantLineHandler.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/DefaultTenantLineHandler.java @@ -22,6 +22,7 @@ import net.sf.jsqlparser.expression.LongValue; import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; import top.continew.starter.extension.tenant.context.TenantContextHolder; +import top.continew.starter.extension.tenant.enums.TenantIsolationLevel; /** * 默认租户行级隔离处理器 @@ -54,7 +55,8 @@ public String getTenantIdColumn() { @Override public boolean ignoreTable(String tableName) { Long tenantId = TenantContextHolder.getTenantId(); - if (null != tenantId && tenantId.equals(tenantProperties.getSuperTenantId())) { + if ((null != tenantId && tenantId.equals(tenantProperties + .getSuperTenantId())) || TenantIsolationLevel.DATASOURCE.equals(TenantContextHolder.getIsolationLevel())) { return true; } return CollUtil.contains(tenantProperties.getIgnoreTables(), tableName); diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceAdvisor.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceAdvisor.java index 75e5bd4..65f936c 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceAdvisor.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceAdvisor.java @@ -65,7 +65,7 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { */ private Pointcut buildPointcut() { AspectJExpressionPointcut cut = new AspectJExpressionPointcut(); - cut.setExpression("!@annotation(top.continew.starter.extension.tenant.annotation.TenantDataSourceIgnore)"); + cut.setExpression("execution(* *..controller..*(..))"); return new ComposablePointcut((Pointcut)cut); } } diff --git a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceInterceptor.java b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceInterceptor.java index b930fa3..1a39fee 100644 --- a/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceInterceptor.java +++ b/continew-starter-extension/continew-starter-extension-tenant/continew-starter-extension-tenant-mp/src/main/java/top/continew/starter/extension/tenant/handler/TenantDataSourceInterceptor.java @@ -20,6 +20,7 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import top.continew.starter.extension.tenant.context.TenantContextHolder; +import top.continew.starter.extension.tenant.enums.TenantIsolationLevel; /** * 租户数据源级隔离拦截器 @@ -37,21 +38,20 @@ public TenantDataSourceInterceptor(TenantDataSourceHandler tenantDataSourceHandl @Override public Object invoke(MethodInvocation invocation) throws Throwable { - Long tenantId = TenantContextHolder.getTenantId(); - if (null == tenantId) { - return invocation.proceed(); - } - // 切换数据源 - boolean isPush = false; - try { - String dataSourceName = tenantId.toString(); - tenantDataSourceHandler.changeDataSource(dataSourceName); - isPush = true; - return invocation.proceed(); - } finally { - if (isPush) { - DynamicDataSourceContextHolder.poll(); + if (TenantContextHolder.getIsolationLevel() == TenantIsolationLevel.DATASOURCE) { + // 切换数据源 + boolean isPush = false; + try { + tenantDataSourceHandler.changeDataSource(TenantContextHolder.getContext().getDataSource()); + isPush = true; + return invocation.proceed(); + } finally { + if (isPush) { + DynamicDataSourceContextHolder.poll(); + } } } + return invocation.proceed(); + } } diff --git a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/ConsoleLogAspect.java b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/ConsoleLogAspect.java index 696ac3a..b9617b0 100644 --- a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/ConsoleLogAspect.java +++ b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/ConsoleLogAspect.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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.log.aop.aspect; import com.alibaba.ttl.TransmittableThreadLocal; @@ -48,7 +64,7 @@ public void doBefore() { // 打印请求日志 if (Boolean.TRUE.equals(logProperties.getIsPrint())) { Instant startTime = Instant.now(); - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); log.info("[{}] {}", request.getMethod(), request.getRequestURI()); @@ -65,16 +81,16 @@ public void afterAdvice() { // 打印请求耗时 if (Boolean.TRUE.equals(logProperties.getIsPrint())) { Instant endTime = Instant.now(); - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); if (attributes == null) { return; } HttpServletRequest request = attributes.getRequest(); HttpServletResponse response = attributes.getResponse(); Duration timeTaken = Duration.between(timeTtl.get(), endTime); - log.info("[{}] {} {} {}ms", request.getMethod(), request.getRequestURI(), - response != null ? response.getStatus() : "N/A", - timeTaken.toMillis()); + log.info("[{}] {} {} {}ms", request.getMethod(), request.getRequestURI(), response != null + ? response.getStatus() + : "N/A", timeTaken.toMillis()); } } } diff --git a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/LogAspect.java b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/LogAspect.java index 2ba0668..f752c48 100644 --- a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/LogAspect.java +++ b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/aspect/LogAspect.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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.log.aop.aspect; import cn.hutool.core.text.CharSequenceUtil; @@ -58,7 +74,7 @@ public void pointcutService() { @Before(value = "pointcutService()") public void doBefore() { Instant startTime = Instant.now(); - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); LogRecord.Started startedLogRecord = LogRecord.start(startTime, new RecordableServletHttpRequest(request)); @@ -66,7 +82,6 @@ public void doBefore() { } } - /** * 处理请求后执行 - 正常返回 * @@ -98,7 +113,7 @@ public void afterThrowing(JoinPoint joinPoint, Exception ex) { private void handleAfterCompletion(JoinPoint joinPoint, Exception ex) { try { Instant endTime = Instant.now(); - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); if (attributes == null) { return; } @@ -110,7 +125,7 @@ private void handleAfterCompletion(JoinPoint joinPoint, Exception ex) { } // 获取方法和类注解信息 - MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + MethodSignature signature = (MethodSignature)joinPoint.getSignature(); Method method = signature.getMethod(); Class targetClass = joinPoint.getTarget().getClass(); @@ -122,9 +137,7 @@ private void handleAfterCompletion(JoinPoint joinPoint, Exception ex) { // 完成日志记录 LogRecord finishedLogRecord = startedLogRecord - .finish(endTime, - new RecordableServletHttpResponse(response, response.getStatus()), - includeSet); + .finish(endTime, new RecordableServletHttpResponse(response, response.getStatus()), includeSet); // 记录异常 if (ex != null) { finishedLogRecord.getResponse().setStatus(1); diff --git a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogAutoConfiguration.java b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogAutoConfiguration.java index 16ce2f6..9ed5828 100644 --- a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogAutoConfiguration.java +++ b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogAutoConfiguration.java @@ -57,7 +57,7 @@ public LogAutoConfiguration(LogProperties logProperties) { @Bean @ConditionalOnMissingBean public LogAspect logAspect() { - return new LogAspect(logDao(),logProperties); + return new LogAspect(logDao(), logProperties); } /** diff --git a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogProperties.java b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogProperties.java index 4cbc129..8acb8da 100644 --- a/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogProperties.java +++ b/continew-starter-log/continew-starter-log-aop/src/main/java/top/continew/starter/log/aop/autoconfigure/LogProperties.java @@ -49,7 +49,6 @@ public class LogProperties { */ private Set includes = Include.defaultIncludes(); - public boolean isEnabled() { return enabled; } diff --git a/continew-starter-log/continew-starter-log-core/src/main/java/top/continew/starter/log/core/model/LogRecord.java b/continew-starter-log/continew-starter-log-core/src/main/java/top/continew/starter/log/core/model/LogRecord.java index 988f13c..b86b659 100644 --- a/continew-starter-log/continew-starter-log-core/src/main/java/top/continew/starter/log/core/model/LogRecord.java +++ b/continew-starter-log/continew-starter-log-core/src/main/java/top/continew/starter/log/core/model/LogRecord.java @@ -175,6 +175,7 @@ public Instant getTimestamp() { public String getErrorMsg() { return errorMsg; } + public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; }