初始化仓库

This commit is contained in:
2026-04-21 15:08:07 +08:00
parent 444d984122
commit b5119afb9f
195 changed files with 11034 additions and 19 deletions

View File

@@ -0,0 +1,28 @@
package xtools.boot.core;
import org.springframework.context.annotation.Import;
import xtools.boot.core.selector.BootCoreImportSelector;
import xtools.boot.core.utils.ModuleLoadUtils;
/**
* <p>Title : BootCoreConfiguration</p>
* <p>Description : BootCoreConfiguration</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/01/01 09:30
*/
@Import(BootCoreImportSelector.class)
public class BootCoreConfiguration {
/**
* 构造方法
*/
public BootCoreConfiguration() {
ModuleLoadUtils.loadSuccess(BootCoreConfiguration.class);
}
}

View File

@@ -0,0 +1,98 @@
package xtools.boot.core.holder;
import xtools.base.config.BaseParams;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* <p>Title : CommonHolder</p>
* <p>Description : CommonHolder</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/1/31 21:20
*/
public class CommonHolder implements BaseParams {
/**
* Mvc通用信息
*/
private static final ScopedValue<Map<String, Object>> COMMON_INFO = ScopedValue.newInstance();
/**
* 获取通用信息 Holder
*
* @return 通用信息
*/
public static ScopedValue<Map<String, Object>> getScoped() {
return COMMON_INFO;
}
/**
* 创建通用信息
*
* @return 通用信息
*/
public static Map<String, Object> create() {
return new HashMap<>(16);
}
/**
* 获取通用信息
*
* @return 通用信息
*/
public static Map<String, Object> get() {
if (!COMMON_INFO.isBound()) {
return null;
}
return COMMON_INFO.get();
}
/**
* 设置通用信息
*
* @param key Key
* @param value Value
*/
public static void set(String key, Object value) {
Map<String, Object> map = get();
if (Objects.nonNull(map)) {
map.put(key, value);
}
}
/**
* 获取通用信息
*
* @param key Key
* @return Value
*/
public static Object get(String key) {
Map<String, Object> map = get();
if (Objects.nonNull(map)) {
return map.get(key);
}
return null;
}
/**
* 获取通用信息
*
* @param key Key
* @return Value
*/
public static boolean getBoolean(String key) {
Map<String, Object> map = get();
if (Objects.nonNull(map) && map.get(key) instanceof Boolean value) {
return value;
}
return false;
}
}

View File

@@ -0,0 +1,25 @@
package xtools.boot.core.interfaces;
import java.util.Set;
/**
* <p>Title : FilterWhitelist</p>
* <p>Description : FilterWhitelist</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/3/8 12:23
*/
public interface FilterWhitelist {
/**
* 添加过滤器白名单
*
* @return 过滤器白名单
*/
Set<String> add();
}

View File

@@ -0,0 +1,34 @@
package xtools.boot.core.interfaces;
/**
* <p>Title : JobInterface</p>
* <p>Description : JobInterface</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/3/12 20:52
*/
public interface JobInterface {
/**
* 执行任务
*
* @throws Exception 任务执行异常
*/
void execute() throws Exception;
/**
* 初始化任务
*/
default void init() {
}
/**
* 销毁任务
*/
default void destroy() {
}
}

View File

@@ -0,0 +1,36 @@
package xtools.boot.core.selector;
import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* <p>Title : BootCoreImportSelector</p>
* <p>Description : BootCoreImportSelector</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/01/01 09:30
*/
public class BootCoreImportSelector implements ImportBeanDefinitionRegistrar {
/**
* 根据给定的注释元数据,根据需要注册bean
*
* @param importingClassMetadata AnnotationMetadata
* @param registry BeanDefinitionRegistry
*/
@Override
public void registerBeanDefinitions(@NonNull AnnotationMetadata importingClassMetadata, @NonNull BeanDefinitionRegistry registry) {
// 构建扫描对象
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, true);
// 扫描包下路径
scanner.scan("xtools.boot.core");
}
}

View File

@@ -0,0 +1,67 @@
package xtools.boot.core.utils;
import xtools.base.config.BaseParams;
import xtools.core.StringUtils;
import xtools.core.encrypt.Md5Utils;
import java.util.List;
/**
* <p>Title : AddrUtils</p>
* <p>Description : AddrUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/3/13 15:09
*/
public class AddrUtils implements BaseParams {
/**
* 本地IP列表
*/
private static final List<String> LOCAL_IP_LIST;
// 初始化
static {
LOCAL_IP_LIST = List.of(
"127.0.0.1",
"localhost"
);
}
/**
* 是否为本地IP
*
* @param ip IP
* @return true or false
*/
public static boolean isLocalIp(String ip) {
if (StringUtils.isEmpty(ip)) {
return true;
}
return LOCAL_IP_LIST.contains(ip);
}
/**
* 根据IP地址获取通用地址code
*
* @param country 国家
* @param province 省份
* @param city 城市
* @return 通用地址code
*/
public static String getCode(String country, String province, String city) {
String code = country;
if (StringUtils.isNotBlank(province)) {
code += CP_LINE + province;
}
if (StringUtils.isNotBlank(city)) {
code += CP_LINE + city;
}
return Md5Utils.encryptToString(code);
}
}

View File

@@ -0,0 +1,33 @@
package xtools.boot.core.utils;
import xtools.core.extend.TemplateUtils;
/**
* <p>Title : AppUtils</p>
* <p>Description : AppUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2025/12/23 09:44
*/
public class AppUtils {
/**
* 应用启动信息
*/
private static final String APP_START_INFO = "应用启动成功,总耗时{}毫秒";
/**
* 获取启动信息
*
* @param startTime 启动时间
* @return 启动信息
*/
public static String info(long startTime) {
return TemplateUtils.format(APP_START_INFO, startTime);
}
}

View File

@@ -0,0 +1,42 @@
package xtools.boot.core.utils;
import xtools.boot.api.enums.BaseEnum;
import xtools.boot.api.model.EnumInfoDto;
import xtools.core.ArrUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* <p>Title : EnumUtils</p>
* <p>Description : EnumUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/2/14 16:29
*/
public class EnumUtils implements Serializable {
/**
* 获取枚举信息
*
* @param list 枚举值列表
* @return 枚举的详细信息
*/
public static List<EnumInfoDto> getEnumInfos(BaseEnum... list) {
if (ArrUtils.isEmpty(list)) {
return null;
}
List<EnumInfoDto> dataList = new ArrayList<>();
for (BaseEnum item : list) {
dataList.add(new EnumInfoDto(item.code(), item.desc()));
}
return dataList;
}
}

View File

@@ -0,0 +1,53 @@
package xtools.boot.core.utils;
import lombok.extern.slf4j.Slf4j;
import xtools.core.CollectionUtils;
import xtools.core.sys.SysBaseInfoUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* <p>Title : JarUtils</p>
* <p>Description : JarUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/2/18 20:57
*/
@Slf4j
public class JarUtils implements Serializable {
/**
* 获取所有jar名称
*
* @return jar名称
*/
public static List<String> getJarName() {
String end = "jar";
List<String> mfPath = null;
try {
mfPath = SysBaseInfoUtils.getMfPath();
} catch (Exception e) {
log.error("获取[MANIFEST.MF]文件路径失败", e);
}
if (CollectionUtils.isEmpty(mfPath)) {
return null;
}
List<String> jarList = new ArrayList<>();
mfPath.stream().filter(Objects::nonNull).forEach(item -> {
item = item.replaceAll("!/META-INF/MANIFEST.MF", "");
item = item.substring(item.lastIndexOf("/") + 1);
if (item.endsWith(end)) {
jarList.add(item);
}
});
return jarList.stream().sorted().toList();
}
}

View File

@@ -0,0 +1,32 @@
package xtools.boot.core.utils;
import lombok.extern.slf4j.Slf4j;
/**
* <p>Title : ModuleLoadUtils</p>
* <p>Description : ModuleLoadUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/1/5 09:20
*/
@Slf4j
public class ModuleLoadUtils {
/**
* 加载成功模版
*/
private static final String LOAD_TEMPLATE = "模块[{}]加载成功";
/**
* 加载成功
*/
public static void loadSuccess(Class<?> clazz) {
String packageName = clazz.getPackageName();
log.info(LOAD_TEMPLATE, packageName);
}
}

View File

@@ -0,0 +1,84 @@
package xtools.boot.core.utils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import xtools.core.ArrUtils;
import xtools.core.CollectionUtils;
import java.util.List;
import java.util.Set;
/**
* <p>Title : PathPatternUtils</p>
* <p>Description : PathPatternUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/2/8 09:05
*/
public class PathPatternUtils {
/**
* 路径匹配
*
* @param pathPatterns 路径规则
* @param path 路径
* @return 结果
*/
public static boolean match(String[] pathPatterns, String path) {
if (ArrUtils.isEmpty(pathPatterns)) {
return false;
}
PathMatcher pm = new AntPathMatcher();
for (String pathPattern : pathPatterns) {
if (pm.match(pathPattern, path)) {
return true;
}
}
return false;
}
/**
* 路径匹配
*
* @param pathPatterns 路径规则
* @param path 路径
* @return 结果
*/
public static boolean match(List<String> pathPatterns, String path) {
if (CollectionUtils.isEmpty(pathPatterns)) {
return false;
}
PathMatcher pm = new AntPathMatcher();
for (String pathPattern : pathPatterns) {
if (pm.match(pathPattern, path)) {
return true;
}
}
return false;
}
/**
* 路径匹配
*
* @param pathPatterns 路径规则
* @param path 路径
* @return 结果
*/
public static boolean match(Set<String> pathPatterns, String path) {
if (CollectionUtils.isEmpty(pathPatterns)) {
return false;
}
PathMatcher pm = new AntPathMatcher();
for (String pathPattern : pathPatterns) {
if (pm.match(pathPattern, path)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,211 @@
package xtools.boot.core.utils;
import lombok.Getter;
import org.jspecify.annotations.NonNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import xtools.base.exception.CommonException;
import xtools.boot.api.enums.BootError;
import java.util.Collection;
import java.util.LinkedList;
/**
* <p>Title : SpringContextUtils</p>
* <p>Description : SpringContextUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/01/01 09:30
*/
@Order(-1)
@Component
public class SpringContextUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
/**
* "@PostConstruct"注解标记的类中,由于ApplicationContext还未加载,导致空指针
* 因此实现BeanFactoryPostProcessor注入ConfigurableListableBeanFactory实现bean的操作
*/
private static ConfigurableListableBeanFactory beanFactory;
/**
* Spring 应用上下文环境
*/
@Getter
private static ApplicationContext applicationContext;
/**
* 获取 ListableBeanFactory
*
* @return ListableBeanFactory
*/
public static ListableBeanFactory getBeanFactory() {
return null == beanFactory ? applicationContext : beanFactory;
}
/**
* 获取 ConfigurableListableBeanFactory
*
* @return ConfigurableListableBeanFactory
*/
public static ConfigurableListableBeanFactory getConfigurableBeanFactory() {
ConfigurableListableBeanFactory factory = null;
if (null != beanFactory) {
factory = beanFactory;
} else if (applicationContext instanceof ConfigurableApplicationContext) {
factory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
}
return factory;
}
/**
* 根据类的类型获取对应的 Bean
*
* @param <T> 类的类型
* @param requiredType 类型
* @return Bean
*/
public static <T> T getBean(Class<T> requiredType) {
try {
return getBeanFactory().getBean(requiredType);
} catch (Exception e) {
throw CommonException.create(BootError.SPRING_BASE, e, "根据类的类型获取对应的 Bean");
}
}
/**
* 根据类的类型获取对应的 Bean
*
* @param <T> 类的类型
* @param requiredType 类型
* @return Bean
*/
public static <T> T getBeanDefNull(Class<T> requiredType) {
try {
return getBeanFactory().getBean(requiredType);
} catch (Exception e) {
return null;
}
}
/**
* 根据类的类型获取对应的 Bean 列表
*
* @param <T> 类的类型
* @param requiredType 类型
* @return Bean 列表
*/
public static <T> Collection<T> getBeanList(Class<T> requiredType) {
try {
return new LinkedList<>(getBeanFactory().getBeansOfType(requiredType).values());
} catch (Exception e) {
throw CommonException.create(BootError.SPRING_BASE, e, "根据类的类型获取对应的 Bean 列表");
}
}
/**
* 根据 Bean 名称获取对象
*
* @param name Bean 名称
* @return Bean
*/
public static Object getBean(String name) {
try {
return getBeanFactory().getBean(name);
} catch (Exception e) {
throw CommonException.create(BootError.SPRING_BASE, e, "根据 Bean 名称获取对象");
}
}
/**
* 根据 Bean 名称获取对象
*
* @param name Bean 名称
* @return Bean
*/
public static Object getBeanDefNull(String name) {
try {
return getBeanFactory().getBean(name);
} catch (Exception e) {
return null;
}
}
/**
* 动态向 Spring 注册 Bean
*
* @param <T> Bean 类型
* @param beanName 名称
* @param bean Bean
*/
public static <T> void registerBean(String beanName, T bean) {
final ConfigurableListableBeanFactory factory = getConfigurableBeanFactory();
factory.autowireBean(bean);
factory.registerSingleton(beanName, bean);
}
/**
* 注销bean(将Spring中的bean注销请谨慎使用)
*
* @param beanName bean 名称
*/
public static void unregisterBean(String beanName) {
final ConfigurableListableBeanFactory factory = getConfigurableBeanFactory();
if (factory instanceof DefaultSingletonBeanRegistry registry) {
registry.destroySingleton(beanName);
}
}
/**
* 发布事件
*
* @param event 待发布的事件
*/
public static void publishAppEvent(ApplicationEvent event) {
publishEvent(event);
}
/**
* 发布事件
*
* @param event 待发布的事件
*/
public static void publishEvent(Object event) {
if (null != applicationContext) {
applicationContext.publishEvent(event);
}
}
/**
* 设置 Spring 应用上下文环境
*
* @param applicationContext ApplicationContext
*/
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
/**
* 设置 beanFactory
*
* @param beanFactory ConfigurableListableBeanFactory
*/
@Override
public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringContextUtils.beanFactory = beanFactory;
}
}

View File

@@ -0,0 +1,53 @@
package xtools.boot.core.utils;
import xtools.base.exception.CommonException;
import xtools.boot.api.enums.BootError;
import xtools.core.StringUtils;
import xtools.core.enums.TimePattern;
import xtools.core.extend.CheckUtils;
import xtools.core.time.InstantUtils;
import java.io.Serializable;
import java.time.Instant;
/**
* <p>Title : TimeUtils</p>
* <p>Description : TimeUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/1/6 14:20
*/
public class TimeUtils implements Serializable {
/**
* 时间分隔符
*/
private static final String T = "T";
/**
* 时间转换
*
* @param time 时间
* @return 时间
*/
public static Instant toInstant(String time) {
if (StringUtils.isBlank(time)) {
return null;
}
if (time.contains(T)) {
return Instant.parse(time);
}
if (CheckUtils.pattern(TimePattern.YMDHMS.regex(), time)) {
return InstantUtils.parse(time, TimePattern.YMDHMS);
} else if (CheckUtils.pattern(TimePattern.YMD.regex(), time)) {
return InstantUtils.parse(time, TimePattern.YMD);
} else {
throw CommonException.create(BootError.TIME_CONVERT, time);
}
}
}

View File

@@ -0,0 +1,38 @@
package xtools.boot.core.utils;
import xtools.boot.api.model.dto.resp.TreeResp;
import java.util.ArrayList;
import java.util.List;
/**
* <p>Title : TreeUtils</p>
* <p>Description : TreeUtils</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 5.0.0
* @date : 2026/1/30 09:41
*/
public class TreeUtils {
/**
* 获取子节点
*
* @param id 父级 ID
* @param list 数据级
* @return 子级
*/
public static List<TreeResp> getChild(Long id, List<TreeResp> list) {
List<TreeResp> childList = new ArrayList<>();
list.stream().filter(item -> item.getParentId().equals(id)).forEach(item -> {
List<TreeResp> child = getChild(item.getValue(), list);
item.setChildren(child);
childList.add(item);
});
return childList;
}
}

View File

@@ -0,0 +1 @@
xtools.boot.core.BootCoreConfiguration