调整框架,删除不必要的组件

This commit is contained in:
2025-05-22 15:03:46 +08:00
parent 5bf210cbf4
commit 5ffe1d489f
49 changed files with 104 additions and 1454 deletions

View File

@@ -1,17 +1,15 @@
package com.tashow.cloud.tenant.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.tashow.cloud.common.enums.WebFilterOrderEnum;
import com.tashow.cloud.mybatis.mybatis.core.util.MyBatisUtils;
import com.tashow.cloud.redis.config.TashowCacheProperties;
import com.tashow.cloud.systemapi.api.tenant.TenantApi;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.tashow.cloud.tenant.core.aop.TenantIgnoreAspect;
import com.tashow.cloud.tenant.core.db.TenantDatabaseInterceptor;
import com.tashow.cloud.tenant.core.job.TenantJobAspect;
import com.tashow.cloud.tenant.core.mq.rabbitmq.TenantRabbitMQInitializer;
import com.tashow.cloud.tenant.core.mq.redis.TenantRedisMessageInterceptor;
import com.tashow.cloud.tenant.core.mq.rocketmq.TenantRocketMQInitializer;
import com.tashow.cloud.tenant.core.redis.TenantRedisCacheManager;
import com.tashow.cloud.tenant.core.security.TenantSecurityWebFilter;
import com.tashow.cloud.tenant.core.service.TenantFrameworkService;
@@ -25,7 +23,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.BatchStrategies;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
@@ -97,23 +94,6 @@ public class TenantAutoConfiguration {
return new TenantJobAspect(tenantFrameworkService);
}
// ========== MQ ==========
/**
* 多租户 Redis 消息队列的配置类
*
* 为什么要单独一个配置类呢?如果直接把 TenantRedisMessageInterceptor Bean 的初始化放外面,会报 RedisMessageInterceptor 类不存在的错误
*/
@Configuration
@ConditionalOnClass(name = "com.tashow.cloud.mq.redis.core.RedisMQTemplate")
public static class TenantRedisMQAutoConfiguration {
@Bean
public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() {
return new TenantRedisMessageInterceptor();
}
}
@Bean
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
@@ -121,12 +101,6 @@ public class TenantAutoConfiguration {
return new TenantRabbitMQInitializer();
}
@Bean
@ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate")
public TenantRocketMQInitializer tenantRocketMQInitializer() {
return new TenantRocketMQInitializer();
}
// ========== Redis ==========
@Bean

View File

@@ -1,37 +0,0 @@
package com.tashow.cloud.tenant.core.mq.kafka;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* 多租户的 Kafka 的 {@link EnvironmentPostProcessor} 实现类
*
* Kafka Producer 发送消息时,增加 {@link TenantKafkaProducerInterceptor} 拦截器
*
* @author 芋道源码
*/
@Slf4j
public class TenantKafkaEnvironmentPostProcessor implements EnvironmentPostProcessor {
private static final String PROPERTY_KEY_INTERCEPTOR_CLASSES = "spring.kafka.producer.properties.interceptor.classes";
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 添加 TenantKafkaProducerInterceptor 拦截器
try {
String value = environment.getProperty(PROPERTY_KEY_INTERCEPTOR_CLASSES);
if (StrUtil.isEmpty(value)) {
value = TenantKafkaProducerInterceptor.class.getName();
} else {
value += "," + TenantKafkaProducerInterceptor.class.getName();
}
environment.getSystemProperties().put(PROPERTY_KEY_INTERCEPTOR_CLASSES, value);
} catch (NoClassDefFoundError ignore) {
// 如果触发 NoClassDefFoundError 异常,说明 TenantKafkaProducerInterceptor 类不存在,即没引入 kafka-spring 依赖
}
}
}

View File

@@ -1,48 +0,0 @@
package com.tashow.cloud.tenant.core.mq.kafka;
import cn.hutool.core.util.ReflectUtil;
import com.tashow.cloud.tenant.core.context.TenantContextHolder;
import org.apache.kafka.clients.producer.ProducerInterceptor;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.header.Headers;
import org.springframework.messaging.handler.invocation.InvocableHandlerMethod;
import java.util.Map;
import static com.tashow.cloud.web.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
/**
* Kafka 消息队列的多租户 {@link ProducerInterceptor} 实现类
*
* 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中
* 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现
*
* @author 芋道源码
*/
public class TenantKafkaProducerInterceptor implements ProducerInterceptor<Object, Object> {
@Override
public ProducerRecord<Object, Object> onSend(ProducerRecord<Object, Object> record) {
Long tenantId = TenantContextHolder.getTenantId();
if (tenantId != null) {
Headers headers = (Headers) ReflectUtil.getFieldValue(record, "headers"); // private 属性,没有 get 方法,智能反射
headers.add(HEADER_TENANT_ID, tenantId.toString().getBytes());
}
return record;
}
@Override
public void onAcknowledgement(RecordMetadata metadata, Exception exception) {
}
@Override
public void close() {
}
@Override
public void configure(Map<String, ?> configs) {
}
}

View File

@@ -0,0 +1 @@
package com.tashow.cloud.tenant.core.mq;

View File

@@ -1,43 +0,0 @@
package com.tashow.cloud.tenant.core.mq.redis;
import cn.hutool.core.util.StrUtil;
import com.tashow.cloud.mq.redis.core.interceptor.RedisMessageInterceptor;
import com.tashow.cloud.mq.redis.core.message.AbstractRedisMessage;
import com.tashow.cloud.tenant.core.context.TenantContextHolder;
import static com.tashow.cloud.web.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
/**
* 多租户 {@link AbstractRedisMessage} 拦截器
*
* 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中
* 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中
*
* @author 芋道源码
*/
public class TenantRedisMessageInterceptor implements RedisMessageInterceptor {
@Override
public void sendMessageBefore(AbstractRedisMessage message) {
Long tenantId = TenantContextHolder.getTenantId();
if (tenantId != null) {
message.addHeader(HEADER_TENANT_ID, tenantId.toString());
}
}
@Override
public void consumeMessageBefore(AbstractRedisMessage message) {
String tenantIdStr = message.getHeader(HEADER_TENANT_ID);
if (StrUtil.isNotEmpty(tenantIdStr)) {
TenantContextHolder.setTenantId(Long.valueOf(tenantIdStr));
}
}
@Override
public void consumeMessageAfter(AbstractRedisMessage message) {
// 注意Consumer 是一个逻辑的入口,所以不考虑原本上下文就存在租户编号的情况
TenantContextHolder.clear();
}
}

View File

@@ -1,47 +0,0 @@
package com.tashow.cloud.tenant.core.mq.rocketmq;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.tashow.cloud.tenant.core.context.TenantContextHolder;
import org.apache.rocketmq.client.hook.ConsumeMessageContext;
import org.apache.rocketmq.client.hook.ConsumeMessageHook;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.messaging.handler.invocation.InvocableHandlerMethod;
import java.util.List;
import static com.tashow.cloud.web.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
/**
* RocketMQ 消息队列的多租户 {@link ConsumeMessageHook} 实现类
*
* Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现
*
* @author 芋道源码
*/
public class TenantRocketMQConsumeMessageHook implements ConsumeMessageHook {
@Override
public String hookName() {
return getClass().getSimpleName();
}
@Override
public void consumeMessageBefore(ConsumeMessageContext context) {
// 校验,消息必须是单条,不然设置租户可能不正确
List<MessageExt> messages = context.getMsgList();
Assert.isTrue(messages.size() == 1, "消息条数({})不正确", messages.size());
// 设置租户编号
String tenantId = messages.get(0).getUserProperty(HEADER_TENANT_ID);
if (StrUtil.isNotEmpty(tenantId)) {
TenantContextHolder.setTenantId(Long.parseLong(tenantId));
}
}
@Override
public void consumeMessageAfter(ConsumeMessageContext context) {
TenantContextHolder.clear();
}
}

View File

@@ -1,53 +0,0 @@
package com.tashow.cloud.tenant.core.mq.rocketmq;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl;
import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* 多租户的 RocketMQ 初始化器
*
* @author 芋道源码
*/
public class TenantRocketMQInitializer implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DefaultRocketMQListenerContainer) {
DefaultRocketMQListenerContainer container = (DefaultRocketMQListenerContainer) bean;
initTenantConsumer(container.getConsumer());
} else if (bean instanceof RocketMQTemplate) {
RocketMQTemplate template = (RocketMQTemplate) bean;
initTenantProducer(template.getProducer());
}
return bean;
}
private void initTenantProducer(DefaultMQProducer producer) {
if (producer == null) {
return;
}
DefaultMQProducerImpl producerImpl = producer.getDefaultMQProducerImpl();
if (producerImpl == null) {
return;
}
producerImpl.registerSendMessageHook(new TenantRocketMQSendMessageHook());
}
private void initTenantConsumer(DefaultMQPushConsumer consumer) {
if (consumer == null) {
return;
}
DefaultMQPushConsumerImpl consumerImpl = consumer.getDefaultMQPushConsumerImpl();
if (consumerImpl == null) {
return;
}
consumerImpl.registerConsumeMessageHook(new TenantRocketMQConsumeMessageHook());
}
}

View File

@@ -1,37 +0,0 @@
package com.tashow.cloud.tenant.core.mq.rocketmq;
import com.tashow.cloud.tenant.core.context.TenantContextHolder;
import org.apache.rocketmq.client.hook.SendMessageContext;
import org.apache.rocketmq.client.hook.SendMessageHook;
import static com.tashow.cloud.web.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
/**
* RocketMQ 消息队列的多租户 {@link SendMessageHook} 实现类
*
* Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中
*
* @author 芋道源码
*/
public class TenantRocketMQSendMessageHook implements SendMessageHook {
@Override
public String hookName() {
return getClass().getSimpleName();
}
@Override
public void sendMessageBefore(SendMessageContext sendMessageContext) {
Long tenantId = TenantContextHolder.getTenantId();
if (tenantId == null) {
return;
}
sendMessageContext.getMessage().putUserProperty(HEADER_TENANT_ID, tenantId.toString());
}
@Override
public void sendMessageAfter(SendMessageContext sendMessageContext) {
}
}