rename com.imyeyu.server to com.imyeyu.api
This commit is contained in:
35
src/main/java/com/imyeyu/api/config/AsyncConfig.java
Normal file
35
src/main/java/com/imyeyu/api/config/AsyncConfig.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 异步线程池配置
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2023-08-21 16:22
|
||||
*/
|
||||
@Slf4j
|
||||
@EnableAsync
|
||||
@Configuration
|
||||
public class AsyncConfig implements AsyncConfigurer {
|
||||
|
||||
@Override
|
||||
public @NotNull AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
||||
return (e, method, obj) -> {
|
||||
log.info("Exception message - {}", e.getMessage());
|
||||
log.info("Method name - {}", method.getName());
|
||||
log.info("Parameter values - {}", Arrays.toString(obj));
|
||||
if (e instanceof Exception exception) {
|
||||
log.info("exception: {}", exception.getMessage());
|
||||
}
|
||||
log.error("async uncaught error", e);
|
||||
};
|
||||
}
|
||||
}
|
||||
16
src/main/java/com/imyeyu/api/config/BeanConfig.java
Normal file
16
src/main/java/com/imyeyu/api/config/BeanConfig.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author 夜雨
|
||||
* @since 2025-05-16 18:53
|
||||
*/
|
||||
@Configuration
|
||||
public class BeanConfig {
|
||||
|
||||
public Gson gson() {
|
||||
return new Gson();
|
||||
}
|
||||
}
|
||||
55
src/main/java/com/imyeyu/api/config/CORSConfig.java
Normal file
55
src/main/java/com/imyeyu/api/config/CORSConfig.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 跨域控制
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2021-05-14 09:21
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ConfigurationProperties(prefix = "cors")
|
||||
public class CORSConfig {
|
||||
|
||||
/** 允许跨域的地址 */
|
||||
private String[] allowOrigin;
|
||||
|
||||
/** 是否允许请求带有验证信息 */
|
||||
private boolean allowCredentials;
|
||||
|
||||
/** 允许请求的方法 */
|
||||
private String allowMethods;
|
||||
|
||||
/** 允许服务端访问的客户端请求头 */
|
||||
private String allowHeaders;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<Filter> corsFilter() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
config.addAllowedHeader(allowHeaders);
|
||||
config.addAllowedMethod(allowMethods);
|
||||
config.setAllowCredentials(allowCredentials);
|
||||
config.setAllowedOriginPatterns(Arrays.asList(allowOrigin));
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
|
||||
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
24
src/main/java/com/imyeyu/api/config/MongoConfig.java
Normal file
24
src/main/java/com/imyeyu/api/config/MongoConfig.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import com.mongodb.client.MongoClient;
|
||||
import com.mongodb.client.gridfs.GridFSBucket;
|
||||
import com.mongodb.client.gridfs.GridFSBuckets;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author 夜雨
|
||||
* @since 2024-02-23 10:55
|
||||
*/
|
||||
@Configuration
|
||||
public class MongoConfig {
|
||||
|
||||
@Value("${spring.data.mongodb.database}")
|
||||
private String db;
|
||||
|
||||
@Bean
|
||||
public GridFSBucket gridFSBucket(MongoClient mongoClient) {
|
||||
return GridFSBuckets.create(mongoClient.getDatabase(db));
|
||||
}
|
||||
}
|
||||
268
src/main/java/com/imyeyu/api/config/RedisConfig.java
Normal file
268
src/main/java/com/imyeyu/api/config/RedisConfig.java
Normal file
@@ -0,0 +1,268 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.imyeyu.api.modules.blog.entity.ArticleRanking;
|
||||
import com.imyeyu.api.modules.common.entity.Multilingual;
|
||||
import com.imyeyu.spring.bean.RedisConfigParams;
|
||||
import com.imyeyu.spring.config.AbstractRedisConfig;
|
||||
import com.imyeyu.spring.util.Redis;
|
||||
import com.imyeyu.spring.util.RedisSerializers;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.serializer.support.DeserializingConverter;
|
||||
import org.springframework.core.serializer.support.SerializingConverter;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.SerializationException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* Redis 配置
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2021-02-23 21:36
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@EnableAutoConfiguration
|
||||
@ConfigurationProperties(prefix = "spring.redis")
|
||||
public class RedisConfig extends AbstractRedisConfig {
|
||||
|
||||
// ---------- 连接配置 ----------
|
||||
|
||||
/** 地址 */
|
||||
private String host;
|
||||
|
||||
/** 端口 */
|
||||
private int port;
|
||||
|
||||
/** 密码 */
|
||||
private String password;
|
||||
|
||||
/** 超时(毫秒) */
|
||||
private int timeout;
|
||||
|
||||
/** 连接池 */
|
||||
private Lettuce lettuce;
|
||||
|
||||
/** 数据库 */
|
||||
private Database database;
|
||||
|
||||
/**
|
||||
* 连接池
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2023-08-21 16:23
|
||||
*/
|
||||
@Data
|
||||
public static class Lettuce {
|
||||
|
||||
/** 配置 */
|
||||
private Pool pool;
|
||||
|
||||
/**
|
||||
* 配置
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2023-08-21 16:23
|
||||
*/
|
||||
@Data
|
||||
public static class Pool {
|
||||
|
||||
/** 最大活跃连接 */
|
||||
private int maxActive;
|
||||
|
||||
/** 最小空闲连接 */
|
||||
private int minIdle;
|
||||
|
||||
/** 最大空闲连接 */
|
||||
private int maxIdle;
|
||||
|
||||
/** 最大等待时间(秒) */
|
||||
private int maxWait;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2023-08-21 16:25
|
||||
*/
|
||||
@Data
|
||||
public static class Database {
|
||||
|
||||
/** 分布式锁 */
|
||||
private int locker;
|
||||
|
||||
/** 多语言环境 */
|
||||
private int language;
|
||||
|
||||
/** 多语言键环境 */
|
||||
private int languageMap;
|
||||
|
||||
/** 文章排位 */
|
||||
private int articleRanking;
|
||||
|
||||
/** 文章阅读记录 */
|
||||
private int articleRead;
|
||||
|
||||
/** 用户登录令牌 */
|
||||
private int userToken;
|
||||
|
||||
/** 用户经验值标记 */
|
||||
private int userExpFlag;
|
||||
|
||||
/** 用户邮箱验证 */
|
||||
private int userEmailVerify;
|
||||
|
||||
/** 用户重置密码验证 */
|
||||
private int userResetPWVerify;
|
||||
|
||||
/** 访问频率控制 */
|
||||
private int rateLimit;
|
||||
|
||||
/** 系统配置 */
|
||||
private int setting;
|
||||
|
||||
/** Minecraft 登录 */
|
||||
private int fmcPlayerToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RedisConfigParams configParams() {
|
||||
return new RedisConfigParams() {{
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
setPassword(password);
|
||||
setTimeout(timeout);
|
||||
setMaxActive(lettuce.pool.maxActive);
|
||||
setMinIdle(lettuce.pool.minIdle);
|
||||
setMaxIdle(lettuce.pool.maxIdle);
|
||||
}};
|
||||
}
|
||||
|
||||
/** @return 连接池配置 */
|
||||
@Bean
|
||||
@Override
|
||||
public GenericObjectPoolConfig<?> getPoolConfig() {
|
||||
GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
|
||||
config.setMaxTotal(lettuce.pool.maxActive);
|
||||
config.setMinIdle(lettuce.pool.minIdle);
|
||||
config.setMaxIdle(lettuce.pool.maxIdle);
|
||||
config.setMaxWait(Duration.ofMillis(lettuce.pool.maxWait));
|
||||
return config;
|
||||
}
|
||||
|
||||
/** @return key 生成策略 */
|
||||
@Bean
|
||||
@Override
|
||||
public KeyGenerator keyGenerator() {
|
||||
return (target, method, params) -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(target.getClass().getName());
|
||||
sb.append(method.getName());
|
||||
for (Object obj : params) {
|
||||
sb.append(obj.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
};
|
||||
}
|
||||
|
||||
/** @return 分布式锁, ID: 尝试加锁次数 */
|
||||
@Bean("redisLocker")
|
||||
public Redis<String, Integer> getLockerRedisTemplate() {
|
||||
return getRedis(database.locker, RedisSerializers.STRING, RedisSerializers.INTEGER);
|
||||
}
|
||||
|
||||
/** @return 多语言环境,ID: {@link Multilingual} */
|
||||
@Bean("redisLanguage")
|
||||
public Redis<Long, Multilingual> getLanguageRedisTemplate() {
|
||||
return getRedis(database.language, RedisSerializers.LONG, new RedisSerializer<>() {
|
||||
|
||||
public Multilingual deserialize(@Nullable byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (Multilingual) new DeserializingConverter().convert(bytes);
|
||||
} catch (Exception var3) {
|
||||
throw new SerializationException("Cannot deserialize", var3);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] serialize(@Nullable Multilingual multilingual) {
|
||||
if (multilingual == null) {
|
||||
return new byte[0];
|
||||
} else {
|
||||
try {
|
||||
return new SerializingConverter().convert(multilingual);
|
||||
} catch (Exception var3) {
|
||||
throw new SerializationException("Cannot serialize", var3);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @return 文章访问记录,IP: [文章 ID] */
|
||||
@Bean("redisLanguageMap")
|
||||
public Redis<String, Long> getLanguageMapRedisTemplate() {
|
||||
return getRedis(database.languageMap, RedisSerializers.STRING, RedisSerializers.LONG);
|
||||
}
|
||||
|
||||
/** @return 文章访问统计,文章 ID: {@link ArticleRanking}(JSON) */
|
||||
@Bean("redisArticleRanking")
|
||||
public Redis<Long, ArticleRanking> getArticleRankingRedisTemplate() {
|
||||
return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.gsonSerializer(ArticleRanking.class));
|
||||
}
|
||||
|
||||
/** @return 文章访问记录,IP: [文章 ID] */
|
||||
@Bean("redisArticleRead")
|
||||
public Redis<String, Long> getArticleReadRedisTemplate() {
|
||||
return getRedis(database.articleRead, RedisSerializers.STRING, RedisSerializers.LONG);
|
||||
}
|
||||
|
||||
/** @return 用户登录经验标记,UID: NULL,暂时没有值,数据死亡时间为次日零时 */
|
||||
@Bean("redisUserExpFlag")
|
||||
public Redis<Long, String> getUserExpFlagRedisTemplate() {
|
||||
return getRedis(database.userExpFlag, RedisSerializers.LONG, RedisSerializers.STRING);
|
||||
}
|
||||
|
||||
/** @return 用户邮箱验证密钥,密钥: UID */
|
||||
@Bean("redisUserEmailVerify")
|
||||
public Redis<String, Long> getUserEmailVerifyRedisTemplate() {
|
||||
return getRedis(database.userEmailVerify, RedisSerializers.STRING, RedisSerializers.LONG);
|
||||
}
|
||||
|
||||
/** @return 用户重置密码密钥,密钥: UID */
|
||||
@Bean("redisUserResetPWVerify")
|
||||
public Redis<String, Long> getUserResetPWVerifyRedisTemplate() {
|
||||
return getRedis(database.userResetPWVerify, RedisSerializers.STRING, RedisSerializers.LONG);
|
||||
}
|
||||
|
||||
/** @return 接口访问控制,IP#方法: 生命周期内访问次数 */
|
||||
@Bean("redisRateLimit")
|
||||
public Redis<String, Integer> getRateLimitRedisTemplate() {
|
||||
return getRedis(database.rateLimit, RedisSerializers.STRING, RedisSerializers.INTEGER);
|
||||
}
|
||||
|
||||
/** @return 系统配置,Key 枚举: String 配置值 */
|
||||
@Bean("redisSetting")
|
||||
public Redis<String, String> getSettingRedisTemplate() {
|
||||
return getRedis(database.setting, RedisSerializers.STRING, RedisSerializers.STRING);
|
||||
}
|
||||
|
||||
/** @return Minecraft 登录,令牌: 玩家 ID */
|
||||
@Bean("redisMCPlayerToken")
|
||||
public Redis<String, Long> getMCPlayerLoginRedisTemplate() {
|
||||
return getRedis(database.fmcPlayerToken, RedisSerializers.STRING, RedisSerializers.LONG);
|
||||
}
|
||||
}
|
||||
33
src/main/java/com/imyeyu/api/config/SchedulerConfig.java
Normal file
33
src/main/java/com/imyeyu/api/config/SchedulerConfig.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2024-12-19 23:04
|
||||
*/
|
||||
@Configuration
|
||||
public class SchedulerConfig {
|
||||
|
||||
@Bean
|
||||
public TaskScheduler taskScheduler() {
|
||||
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
|
||||
scheduler.setPoolSize(32);
|
||||
scheduler.initialize();
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ScheduledTaskRegistrar scheduleCronTask(TaskScheduler taskScheduler) {
|
||||
ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
|
||||
registrar.setTaskScheduler(taskScheduler);
|
||||
registrar.afterPropertiesSet();
|
||||
return registrar;
|
||||
}
|
||||
}
|
||||
57
src/main/java/com/imyeyu/api/config/ThreadPoolConfig.java
Normal file
57
src/main/java/com/imyeyu/api/config/ThreadPoolConfig.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 线程池配置
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2023-08-21 16:31
|
||||
*/
|
||||
@Data
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ConfigurationProperties(prefix = "spring.async.thread-pool")
|
||||
public class ThreadPoolConfig {
|
||||
|
||||
/** 核心数量 */
|
||||
private int corePoolSize;
|
||||
|
||||
/** 最大数量 */
|
||||
private int maxPoolSize;
|
||||
|
||||
/** 等待区容量 */
|
||||
private int queueCapacity;
|
||||
|
||||
/** 最大保持活跃时间(秒) */
|
||||
private int keepAliveSeconds;
|
||||
|
||||
/** 最大等待时间(秒) */
|
||||
private int awaitTerminationSeconds;
|
||||
|
||||
/** 线程名称前缀 */
|
||||
private String threadNamePrefix;
|
||||
|
||||
@Bean(name = "threadPoolTaskExecutor")
|
||||
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(corePoolSize);
|
||||
executor.setMaxPoolSize(maxPoolSize);
|
||||
executor.setQueueCapacity(queueCapacity);
|
||||
executor.setKeepAliveSeconds(keepAliveSeconds);
|
||||
executor.setAwaitTerminationSeconds(awaitTerminationSeconds);
|
||||
executor.setThreadNamePrefix(threadNamePrefix);
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
94
src/main/java/com/imyeyu/api/config/WebConfig.java
Normal file
94
src/main/java/com/imyeyu/api/config/WebConfig.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.imyeyu.api.config;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.imyeyu.api.annotation.EnableSettingInterceptor;
|
||||
import com.imyeyu.api.annotation.RequestRateLimitInterceptor;
|
||||
import com.imyeyu.api.annotation.RequiredTokenInterceptor;
|
||||
import com.imyeyu.api.modules.common.entity.Attachment;
|
||||
import com.imyeyu.api.modules.common.vo.user.UserProfileView;
|
||||
import com.imyeyu.api.modules.common.vo.user.UserView;
|
||||
import com.imyeyu.api.modules.minecraft.annotation.RequiredFMCServerTokenInterceptor;
|
||||
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
|
||||
import com.imyeyu.api.modules.mirror.vo.MirrorView;
|
||||
import com.imyeyu.api.modules.system.util.SystemAPIInterceptor;
|
||||
import com.imyeyu.api.util.GsonSerializerAdapter;
|
||||
import com.imyeyu.spring.annotation.RequestSingleParamResolver;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2021-07-20 16:44
|
||||
*/
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
private final SystemAPIInterceptor systemAPIInterceptor;
|
||||
private final GsonSerializerAdapter gsonSerializerAdapter;
|
||||
private final RequiredTokenInterceptor requiredTokenInterceptor;
|
||||
private final EnableSettingInterceptor enableSettingInterceptor;
|
||||
private final RequestSingleParamResolver requestSingleParamResolver;
|
||||
private final RequestRateLimitInterceptor requestRateLimitInterceptor;
|
||||
private final RequiredFMCServerTokenInterceptor requiredFMCServerTokenInterceptor;
|
||||
|
||||
/**
|
||||
* 过滤器
|
||||
*
|
||||
* @param registry 注册表
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(systemAPIInterceptor).addPathPatterns(SystemAPIInterceptor.PATH);
|
||||
registry.addInterceptor(requiredFMCServerTokenInterceptor).addPathPatterns("/fmc/server/**");
|
||||
registry.addInterceptor(requiredTokenInterceptor).addPathPatterns("/**");
|
||||
registry.addInterceptor(enableSettingInterceptor).addPathPatterns("/**");
|
||||
registry.addInterceptor(requestRateLimitInterceptor).addPathPatterns("/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(requestSingleParamResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通信消息转换
|
||||
*
|
||||
* @param converters 转换器
|
||||
*/
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
GsonHttpMessageConverter converter = new GsonHttpMessageConverter() {
|
||||
|
||||
@Override
|
||||
protected void writeInternal(@NotNull Object object, Type type, @NonNull Writer writer) {
|
||||
// 忽略参数类型,因为接口返回对象会被全局返回处理器包装为 TimiResponse,否则会序列化转型错误
|
||||
getGson().toJson(object, writer);
|
||||
}
|
||||
};
|
||||
|
||||
GsonBuilder builder = new GsonBuilder();
|
||||
builder.registerTypeAdapter(Attachment.class, gsonSerializerAdapter);
|
||||
builder.registerTypeAdapter(UserView.class, gsonSerializerAdapter);
|
||||
builder.registerTypeAdapter(MirrorView.class, gsonSerializerAdapter);
|
||||
builder.registerTypeAdapter(UserProfileView.class, gsonSerializerAdapter);
|
||||
builder.registerTypeAdapter(MinecraftPlayer.class, gsonSerializerAdapter);
|
||||
converter.setGson(builder.create());
|
||||
converters.add(converter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.imyeyu.api.config.dbsource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import com.imyeyu.utils.Time;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* ForeverMC 登录校验数据源
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2022-11-29 22:39
|
||||
*/
|
||||
@Configuration
|
||||
@MapperScan(basePackages = "com.imyeyu.api.modules.forevermc.mapper", sqlSessionFactoryRef = "foreverMCSqlSessionFactory")
|
||||
public class ForeverMCDBConfig {
|
||||
|
||||
public static final String ROLLBACKER = "foreverMCTransactionManager";
|
||||
|
||||
@Bean(name = "foreverMCDataSource")
|
||||
@Primary
|
||||
@ConfigurationProperties(prefix = "spring.datasource.forevermc")
|
||||
public DataSource getPrimaryDateSource() throws SQLException {
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
dataSource.setAutoCommit(true);
|
||||
dataSource.setMinimumIdle(10);
|
||||
dataSource.setMaximumPoolSize(100);
|
||||
dataSource.setConnectionTestQuery("SELECT 1");
|
||||
|
||||
dataSource.setMaxLifetime(Time.S * 180);
|
||||
dataSource.setIdleTimeout(Time.S * 120);
|
||||
dataSource.setLoginTimeout(5);
|
||||
dataSource.setValidationTimeout(Time.S * 3);
|
||||
dataSource.setConnectionTimeout(Time.S * 8);
|
||||
dataSource.setLeakDetectionThreshold(Time.S * 180);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "foreverMCSqlSessionFactory")
|
||||
@Primary
|
||||
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("foreverMCDataSource") DataSource datasource) throws Exception {
|
||||
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
|
||||
config.setUseGeneratedKeys(true);
|
||||
config.setMapUnderscoreToCamelCase(true);
|
||||
|
||||
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
|
||||
bean.setDataSource(datasource);
|
||||
bean.setTypeAliasesPackage("com.imyeyu.api.modules.forevermc.entity");
|
||||
bean.setConfiguration(config);
|
||||
return bean.getObject();
|
||||
}
|
||||
|
||||
@Bean("foreverMCSqlSessionTemplate")
|
||||
@Primary
|
||||
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("foreverMCSqlSessionFactory") SqlSessionFactory sessionfactory) {
|
||||
return new SqlSessionTemplate(sessionfactory);
|
||||
}
|
||||
|
||||
@Bean(name = "foreverMCTransactionManager")
|
||||
public PlatformTransactionManager txManager(@Qualifier("foreverMCDataSource") DataSource dataSource) {
|
||||
return new DataSourceTransactionManager(dataSource);
|
||||
}
|
||||
}
|
||||
104
src/main/java/com/imyeyu/api/config/dbsource/GiteaDBConfig.java
Normal file
104
src/main/java/com/imyeyu/api/config/dbsource/GiteaDBConfig.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package com.imyeyu.api.config.dbsource;
|
||||
|
||||
import com.imyeyu.utils.Time;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.type.EnumTypeHandler;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Gitea 数据源
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2022-11-29 22:40
|
||||
*/
|
||||
@Configuration
|
||||
@MapperScan(basePackages = {
|
||||
"com.imyeyu.api.modules.gitea.mapper",
|
||||
}, sqlSessionFactoryRef = "giteaSqlSessionFactory")
|
||||
public class GiteaDBConfig {
|
||||
|
||||
public static final String ROLLBACKER = "giteaTransactionManager";
|
||||
|
||||
@Bean(name = "giteaDataSource")
|
||||
@Primary
|
||||
@ConfigurationProperties(prefix = "spring.datasource.gitea")
|
||||
public DataSource dateSource() throws SQLException {
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
dataSource.setAutoCommit(true);
|
||||
dataSource.setMinimumIdle(10);
|
||||
dataSource.setMaximumPoolSize(100);
|
||||
dataSource.setConnectionTestQuery("SELECT 1");
|
||||
|
||||
dataSource.setMaxLifetime(Time.S * 180);
|
||||
dataSource.setIdleTimeout(Time.S * 120);
|
||||
dataSource.setLoginTimeout(5);
|
||||
dataSource.setValidationTimeout(Time.S * 3);
|
||||
dataSource.setConnectionTimeout(Time.S * 8);
|
||||
dataSource.setLeakDetectionThreshold(Time.S * 180);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "giteaSqlSessionFactory")
|
||||
@Primary
|
||||
public SqlSessionFactory sessionFactory(@Qualifier("giteaDataSource") DataSource datasource) throws Exception {
|
||||
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
|
||||
config.setUseGeneratedKeys(true);
|
||||
config.setMapUnderscoreToCamelCase(true);
|
||||
config.setDefaultEnumTypeHandler(EnumTypeHandler.class);
|
||||
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
{
|
||||
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
|
||||
List<String> mapperLocations = new ArrayList<>();
|
||||
mapperLocations.add("classpath:mapper/gitea/**/*.xml");
|
||||
for (int i = 0; i < mapperLocations.size(); i++) {
|
||||
resources.addAll(List.of(resourceResolver.getResources(mapperLocations.get(i))));
|
||||
}
|
||||
}
|
||||
String[] typeAliases = {
|
||||
"com.imyeyu.api.modules.gitea.entity",
|
||||
};
|
||||
String[] typeHandlers = {
|
||||
"com.imyeyu.api.handler"
|
||||
};
|
||||
|
||||
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
|
||||
bean.setDataSource(datasource);
|
||||
bean.setConfiguration(config);
|
||||
bean.setMapperLocations(resources.toArray(new Resource[0]));
|
||||
bean.setTypeAliasesPackage(String.join(",", typeAliases));
|
||||
bean.setTypeHandlersPackage(String.join(",", typeHandlers));
|
||||
return bean.getObject();
|
||||
}
|
||||
|
||||
|
||||
@Bean("giteaSqlSessionTemplate")
|
||||
@Primary
|
||||
public SqlSessionTemplate sessionTemplate(@Qualifier("giteaSqlSessionFactory") SqlSessionFactory sessionfactory) {
|
||||
return new SqlSessionTemplate(sessionfactory);
|
||||
}
|
||||
|
||||
@Bean(name = "giteaTransactionManager")
|
||||
public PlatformTransactionManager txManager(@Qualifier("giteaDataSource") DataSource dataSource) {
|
||||
return new DataSourceTransactionManager(dataSource);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.imyeyu.api.config.dbsource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import com.imyeyu.utils.Time;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.type.EnumTypeHandler;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TimiServer 数据源
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2022-11-29 22:40
|
||||
*/
|
||||
@Configuration
|
||||
@MapperScan(basePackages = {
|
||||
"com.imyeyu.api.modules.git.mapper",
|
||||
"com.imyeyu.api.modules.bill.mapper",
|
||||
"com.imyeyu.api.modules.blog.mapper",
|
||||
"com.imyeyu.api.modules.lyric.mapper",
|
||||
"com.imyeyu.api.modules.mirror.mapper",
|
||||
"com.imyeyu.api.modules.system.mapper",
|
||||
"com.imyeyu.api.modules.common.mapper",
|
||||
"com.imyeyu.api.modules.minecraft.mapper"
|
||||
}, sqlSessionFactoryRef = "timiServerSqlSessionFactory")
|
||||
public class TimiServerDBConfig {
|
||||
|
||||
public static final String ROLLBACKER = "timiServerTransactionManager";
|
||||
|
||||
@Bean(name = "timiServerDataSource")
|
||||
@Primary
|
||||
@ConfigurationProperties(prefix = "spring.datasource.timiserver")
|
||||
public DataSource getPrimaryDateSource() throws SQLException {
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
dataSource.setAutoCommit(true);
|
||||
dataSource.setMinimumIdle(10);
|
||||
dataSource.setMaximumPoolSize(100);
|
||||
dataSource.setConnectionTestQuery("SELECT 1");
|
||||
|
||||
dataSource.setMaxLifetime(Time.S * 180);
|
||||
dataSource.setIdleTimeout(Time.S * 120);
|
||||
dataSource.setLoginTimeout(5);
|
||||
dataSource.setValidationTimeout(Time.S * 3);
|
||||
dataSource.setConnectionTimeout(Time.S * 8);
|
||||
dataSource.setLeakDetectionThreshold(Time.S * 180);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "timiServerSqlSessionFactory")
|
||||
@Primary
|
||||
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("timiServerDataSource") DataSource datasource) throws Exception {
|
||||
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
|
||||
config.setUseGeneratedKeys(true);
|
||||
config.setMapUnderscoreToCamelCase(true);
|
||||
config.setDefaultEnumTypeHandler(EnumTypeHandler.class);
|
||||
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
{
|
||||
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
|
||||
List<String> mapperLocations = new ArrayList<>();
|
||||
mapperLocations.add("classpath:mapper/git/**/*.xml");
|
||||
mapperLocations.add("classpath:mapper/blog/**/*.xml");
|
||||
mapperLocations.add("classpath:mapper/common/**/*.xml");
|
||||
mapperLocations.add("classpath:mapper/system/**/*.xml");
|
||||
mapperLocations.add("classpath:mapper/minecraft/**/*.xml");
|
||||
for (int i = 0; i < mapperLocations.size(); i++) {
|
||||
resources.addAll(List.of(resourceResolver.getResources(mapperLocations.get(i))));
|
||||
}
|
||||
}
|
||||
String[] typeAliases = {
|
||||
"com.imyeyu.api.modules.git.entity",
|
||||
"com.imyeyu.api.modules.bill.entity",
|
||||
"com.imyeyu.api.modules.blog.entity",
|
||||
"com.imyeyu.api.modules.lyric.entity",
|
||||
"com.imyeyu.api.modules.mirror.entity",
|
||||
"com.imyeyu.api.modules.system.entity",
|
||||
"com.imyeyu.api.modules.common.entity",
|
||||
"com.imyeyu.api.modules.minecraft.entity"
|
||||
};
|
||||
String[] typeHandlers = {
|
||||
"com.imyeyu.api.handler"
|
||||
};
|
||||
|
||||
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
|
||||
bean.setDataSource(datasource);
|
||||
bean.setConfiguration(config);
|
||||
bean.setMapperLocations(resources.toArray(new Resource[0]));
|
||||
bean.setTypeAliasesPackage(String.join(",", typeAliases));
|
||||
bean.setTypeHandlersPackage(String.join(",", typeHandlers));
|
||||
return bean.getObject();
|
||||
}
|
||||
|
||||
|
||||
@Bean("timiServerSqlSessionTemplate")
|
||||
@Primary
|
||||
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("timiServerSqlSessionFactory") SqlSessionFactory sessionfactory) {
|
||||
return new SqlSessionTemplate(sessionfactory);
|
||||
}
|
||||
|
||||
@Bean(name = "timiServerTransactionManager")
|
||||
public PlatformTransactionManager txManager(@Qualifier("timiServerDataSource") DataSource dataSource) {
|
||||
return new DataSourceTransactionManager(dataSource);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user