提交 | 用户 | 时间
|
e7c126
|
1 |
package com.iailab.framework.tenant.config; |
H |
2 |
|
|
3 |
import com.iailab.framework.common.enums.WebFilterOrderEnum; |
|
4 |
import com.iailab.framework.mybatis.core.util.MyBatisUtils; |
|
5 |
import com.iailab.framework.redis.config.IailabCacheProperties; |
|
6 |
import com.iailab.framework.tenant.core.aop.TenantIgnoreAspect; |
|
7 |
import com.iailab.framework.tenant.core.db.TenantDatabaseInterceptor; |
|
8 |
import com.iailab.framework.tenant.core.job.TenantJobAspect; |
|
9 |
import com.iailab.framework.tenant.core.mq.rabbitmq.TenantRabbitMQInitializer; |
|
10 |
import com.iailab.framework.tenant.core.mq.redis.TenantRedisMessageInterceptor; |
|
11 |
import com.iailab.framework.tenant.core.mq.rocketmq.TenantRocketMQInitializer; |
|
12 |
import com.iailab.framework.tenant.core.redis.TenantRedisCacheManager; |
|
13 |
import com.iailab.framework.tenant.core.security.TenantSecurityWebFilter; |
|
14 |
import com.iailab.framework.tenant.core.service.TenantFrameworkService; |
|
15 |
import com.iailab.framework.tenant.core.service.TenantFrameworkServiceImpl; |
|
16 |
import com.iailab.framework.tenant.core.web.TenantContextWebFilter; |
|
17 |
import com.iailab.framework.web.config.WebProperties; |
|
18 |
import com.iailab.framework.web.core.handler.GlobalExceptionHandler; |
|
19 |
import com.iailab.module.system.api.tenant.TenantApi; |
|
20 |
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
|
21 |
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; |
|
22 |
import org.springframework.boot.autoconfigure.AutoConfiguration; |
|
23 |
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
|
24 |
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
|
25 |
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
|
26 |
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
|
27 |
import org.springframework.context.annotation.Bean; |
|
28 |
import org.springframework.context.annotation.Configuration; |
|
29 |
import org.springframework.context.annotation.Primary; |
|
30 |
import org.springframework.data.redis.cache.BatchStrategies; |
|
31 |
import org.springframework.data.redis.cache.RedisCacheConfiguration; |
|
32 |
import org.springframework.data.redis.cache.RedisCacheManager; |
|
33 |
import org.springframework.data.redis.cache.RedisCacheWriter; |
|
34 |
import org.springframework.data.redis.connection.RedisConnectionFactory; |
|
35 |
import org.springframework.data.redis.core.RedisTemplate; |
|
36 |
|
|
37 |
import java.util.Objects; |
|
38 |
|
|
39 |
@AutoConfiguration |
|
40 |
@ConditionalOnProperty(prefix = "iailab.tenant", value = "enable", matchIfMissing = true) // 允许使用 iailab.tenant.enable=false 禁用多租户 |
|
41 |
@EnableConfigurationProperties(TenantProperties.class) |
|
42 |
public class IailabTenantAutoConfiguration { |
|
43 |
|
|
44 |
@Bean |
|
45 |
public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) { |
|
46 |
return new TenantFrameworkServiceImpl(tenantApi); |
|
47 |
} |
|
48 |
|
|
49 |
// ========== AOP ========== |
|
50 |
|
|
51 |
@Bean |
|
52 |
public TenantIgnoreAspect tenantIgnoreAspect() { |
|
53 |
return new TenantIgnoreAspect(); |
|
54 |
} |
|
55 |
|
|
56 |
// ========== DB ========== |
|
57 |
|
|
58 |
@Bean |
|
59 |
public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties properties, |
|
60 |
MybatisPlusInterceptor interceptor) { |
|
61 |
TenantLineInnerInterceptor inner = new TenantLineInnerInterceptor(new TenantDatabaseInterceptor(properties)); |
|
62 |
// 添加到 interceptor 中 |
|
63 |
// 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定 |
|
64 |
MyBatisUtils.addInterceptor(interceptor, inner, 0); |
|
65 |
return inner; |
|
66 |
} |
|
67 |
|
|
68 |
// ========== WEB ========== |
|
69 |
|
|
70 |
@Bean |
|
71 |
public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter() { |
|
72 |
FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>(); |
|
73 |
registrationBean.setFilter(new TenantContextWebFilter()); |
|
74 |
registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER); |
|
75 |
return registrationBean; |
|
76 |
} |
|
77 |
|
|
78 |
// ========== Security ========== |
|
79 |
|
|
80 |
@Bean |
|
81 |
public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties, |
|
82 |
WebProperties webProperties, |
|
83 |
GlobalExceptionHandler globalExceptionHandler, |
|
84 |
TenantFrameworkService tenantFrameworkService) { |
|
85 |
FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>(); |
|
86 |
registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties, |
|
87 |
globalExceptionHandler, tenantFrameworkService)); |
|
88 |
registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); |
|
89 |
return registrationBean; |
|
90 |
} |
|
91 |
|
|
92 |
// ========== Job ========== |
|
93 |
|
|
94 |
@Bean |
|
95 |
@ConditionalOnClass(name = "com.xxl.job.core.handler.annotation.XxlJob") |
|
96 |
public TenantJobAspect tenantJobAspect(TenantFrameworkService tenantFrameworkService) { |
|
97 |
return new TenantJobAspect(tenantFrameworkService); |
|
98 |
} |
|
99 |
|
|
100 |
// ========== MQ ========== |
|
101 |
|
|
102 |
/** |
|
103 |
* 多租户 Redis 消息队列的配置类 |
|
104 |
* |
|
105 |
* 为什么要单独一个配置类呢?如果直接把 TenantRedisMessageInterceptor Bean 的初始化放外面,会报 RedisMessageInterceptor 类不存在的错误 |
|
106 |
*/ |
|
107 |
@Configuration |
|
108 |
@ConditionalOnClass(name = "com.iailab.framework.mq.redis.core.RedisMQTemplate") |
|
109 |
public static class TenantRedisMQAutoConfiguration { |
|
110 |
|
|
111 |
@Bean |
|
112 |
public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() { |
|
113 |
return new TenantRedisMessageInterceptor(); |
|
114 |
} |
|
115 |
|
|
116 |
} |
|
117 |
|
|
118 |
@Bean |
|
119 |
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate") |
|
120 |
public TenantRabbitMQInitializer tenantRabbitMQInitializer() { |
|
121 |
return new TenantRabbitMQInitializer(); |
|
122 |
} |
|
123 |
|
|
124 |
@Bean |
|
125 |
@ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate") |
|
126 |
public TenantRocketMQInitializer tenantRocketMQInitializer() { |
|
127 |
return new TenantRocketMQInitializer(); |
|
128 |
} |
|
129 |
|
|
130 |
// ========== Redis ========== |
|
131 |
|
|
132 |
@Bean |
|
133 |
@Primary // 引入租户时,tenantRedisCacheManager 为主 Bean |
|
134 |
public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate, |
|
135 |
RedisCacheConfiguration redisCacheConfiguration, |
4a47e4
|
136 |
IailabCacheProperties iailabCacheProperties, |
H |
137 |
TenantProperties tenantProperties) { |
e7c126
|
138 |
// 创建 RedisCacheWriter 对象 |
H |
139 |
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory()); |
|
140 |
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory, |
|
141 |
BatchStrategies.scan(iailabCacheProperties.getRedisScanBatchSize())); |
|
142 |
// 创建 TenantRedisCacheManager 对象 |
4a47e4
|
143 |
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches()); |
e7c126
|
144 |
} |
H |
145 |
} |