diff --git a/cool-admin.iml b/cool-admin.iml
index 738cf87..d001a39 100644
--- a/cool-admin.iml
+++ b/cool-admin.iml
@@ -1,11 +1,8 @@
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/java/com/cool/CoolApplication.java b/src/main/java/com/cool/CoolApplication.java
index 87be694..aff43b2 100644
--- a/src/main/java/com/cool/CoolApplication.java
+++ b/src/main/java/com/cool/CoolApplication.java
@@ -1,17 +1,22 @@
package com.cool;
+import com.cool.core.util.PathUtils;
+import com.tangzc.autotable.springboot.EnableAutoTable;
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
-import com.tangzc.autotable.springboot.EnableAutoTable;
-
/**
* CoolApplication - 应用程序的主类
* 该类配置并运行应用程序。
*/
+@Slf4j
@EnableAutoTable // 开启自动建表
@EnableAsync // 开启异步处理
@EnableCaching // 开启缓存
@@ -19,7 +24,51 @@ import com.tangzc.autotable.springboot.EnableAutoTable;
@MapperScan("com.cool.modules.*.mapper") // 扫描指定包中的MyBatis映射器
public class CoolApplication {
+ private static volatile ConfigurableApplicationContext context;
+ private static ClassLoader mainThreadClassLoader;
+
public static void main(String[] args) {
- SpringApplication.run(CoolApplication.class, args);
+ mainThreadClassLoader = Thread.currentThread().getContextClassLoader();
+ context = SpringApplication.run(CoolApplication.class, args);
}
-}
\ No newline at end of file
+
+ /**
+ * 通过关闭当前上下文并启动新上下文来重启应用程序。
+ */
+ public static void restart(List javaPathList) {
+ // 从当前上下文获取应用程序参数
+ ApplicationArguments args = context.getBean(ApplicationArguments.class);
+
+ // 创建新线程来重启应用程序
+ Thread thread = new Thread(() -> {
+ try {
+ // 关闭当前应用程序上下文
+ context.close();
+ // 等待上下文完全关闭
+ while (context.isActive()) {
+ Thread.sleep(100);
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ // 加载动态生成的代码
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ javaPathList.forEach(javaPath -> {
+ try {
+ classLoader.loadClass(PathUtils.getClassName(javaPath));
+ } catch (ClassNotFoundException e) {
+ log.error("loadClassErr {}", javaPath, e);
+ }
+ });
+ // 使用相同的参数运行Spring Boot应用程序并设置上下文
+ context = SpringApplication.run(CoolApplication.class, args.getSourceArgs());
+ });
+ // 设置线程的上下文类加载器
+ thread.setContextClassLoader(mainThreadClassLoader);
+ // 确保线程不是守护线程
+ thread.setDaemon(false);
+ // 启动线程
+ thread.start();
+ }
+
+}
diff --git a/src/main/java/com/cool/core/file/strategy/LocalFileUploadStrategy.java b/src/main/java/com/cool/core/file/strategy/LocalFileUploadStrategy.java
index 904d0be..ae7274d 100644
--- a/src/main/java/com/cool/core/file/strategy/LocalFileUploadStrategy.java
+++ b/src/main/java/com/cool/core/file/strategy/LocalFileUploadStrategy.java
@@ -11,13 +11,11 @@ import com.cool.core.exception.CoolPreconditions;
import com.cool.core.file.UpLoadModeType;
import com.cool.modules.plugin.entity.PluginInfoEntity;
import jakarta.servlet.http.HttpServletRequest;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
-
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@@ -47,16 +45,16 @@ public class LocalFileUploadStrategy implements FileUploadStrategy {
String date = DateUtil.format(new Date(),
DatePattern.PURE_DATE_PATTERN);
String relativePath =
- "/" + localFileProperties.getUploadPath() + "/" + date;
+ File.separator + localFileProperties.getUploadPath() + File.separator + date;
FileUtil.mkdir(filePath + relativePath);
for (MultipartFile file : files) {
// 保存文件
String fileName = StrUtil.uuid().replaceAll("-", "") + getExtensionName(
Objects.requireNonNull(file.getOriginalFilename()));
- file.transferTo(new File(filePath + "/" + relativePath
- + "/" + fileName));
- fileUrls.add(baseUrl + "/" + date + "/" + fileName);
+ file.transferTo(new File(filePath + File.separator + relativePath
+ + File.separator + fileName));
+ fileUrls.add(baseUrl + File.separator + date + File.separator + fileName);
}
if (fileUrls.size() == 1) {
return fileUrls.get(0);
diff --git a/src/main/java/com/cool/core/plugin/service/CoolPluginService.java b/src/main/java/com/cool/core/plugin/service/CoolPluginService.java
index 4155a7c..10d97cf 100644
--- a/src/main/java/com/cool/core/plugin/service/CoolPluginService.java
+++ b/src/main/java/com/cool/core/plugin/service/CoolPluginService.java
@@ -94,7 +94,7 @@ public class CoolPluginService {
String pathStr = pluginPath;
if (!PathUtils.isAbsolutePath(pluginPath)) {
// 相对路径
- pathStr = System.getProperty("user.dir") + "/" + pluginPath;
+ pathStr = System.getProperty("user.dir") + File.separator + pluginPath;
}
// 将路径字符串转换为 Path 对象
Path path = Paths.get(pathStr);
@@ -104,7 +104,7 @@ public class CoolPluginService {
Files.createDirectories(path);
}
fileName =
- path + "/" + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar";
+ path + File.separator + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar";
jarFile = new File(fileName);
file.transferTo(jarFile);
// 加载jar
diff --git a/src/main/java/com/cool/core/util/CompilerUtils.java b/src/main/java/com/cool/core/util/CompilerUtils.java
index 2f6f2d9..8f850f9 100644
--- a/src/main/java/com/cool/core/util/CompilerUtils.java
+++ b/src/main/java/com/cool/core/util/CompilerUtils.java
@@ -3,13 +3,14 @@ package com.cool.core.util;
import cn.hutool.core.io.FileUtil;
import com.mybatisflex.processor.MybatisFlexProcessor;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
import java.util.List;
import javax.annotation.processing.Processor;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
public class CompilerUtils {
@@ -21,66 +22,131 @@ public class CompilerUtils {
FileUtil.del(filePathStr);
File file = FileUtil.touch(filePathStr);
FileUtil.appendString(content, file, StandardCharsets.UTF_8.name());
+ compileAndSave(filePathStr);
}
- public static void createMapper(String actModulePath, String fileName, String mapper) {
- String pathStr = actModulePath + "/mapper/";
+ public static String createMapper(String actModulePath, String fileName, String mapper) {
+ String pathStr = actModulePath + File.separator + "mapper" + File.separator;
String filePathStr = pathStr + fileName + "Mapper.java";
createFile(mapper, filePathStr);
+ return filePathStr;
}
- public static void createServiceImpl(String actModulePath, String fileName,
+ public static String createServiceImpl(String actModulePath, String fileName,
String serviceImpl) {
- String pathStr = actModulePath + "/service/impl/";
+ String pathStr = actModulePath + File.separator + "service" + File.separator + "impl" + File.separator;
String filePathStr = pathStr + fileName + "ServiceImpl.java";
createFile(serviceImpl, filePathStr);
+ return filePathStr;
}
- public static void createService(String actModulePath, String fileName, String service) {
- String pathStr = actModulePath + "/service/";
+ public static String createService(String actModulePath, String fileName, String service) {
+ String pathStr = actModulePath + File.separator + "service" + File.separator;
String filePathStr = pathStr + fileName + "Service.java";
createFile(service, filePathStr);
+ return filePathStr;
}
public static String createEntity(String actModulePath, String fileName, String entity) {
- String pathStr = actModulePath + "/entity/";
+ String pathStr = actModulePath + File.separator + "entity" + File.separator;
String filePathStr = pathStr + fileName + "Entity.java";
createFile(entity, filePathStr);
return filePathStr;
}
- public static void createController(String actModulePath, String fileName, String controller) {
- String pathStr = actModulePath + "/controller/admin/";
+ public static String createController(String actModulePath, String fileName, String controller) {
+ String pathStr = actModulePath + File.separator + "controller" + File.separator + "admin" + File.separator;
String filePathStr = pathStr + "Admin" + fileName + "Controller.java";
createFile(controller, filePathStr);
+ return filePathStr;
}
public static String createModule(String modulesPath, String module) {
- String pathStr = modulesPath + "/" + module;
+ String pathStr = modulesPath + File.separator + module;
PathUtils.noExistsMk(pathStr);
return pathStr;
}
- public static void compilerEntityTableDef(String path) {
-// JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
-// StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
-//
-// Iterable extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(
-// path);
-//
-// // 设置注解处理器
-// Iterable extends Processor> processors = Arrays.asList(new MybatisFlexProcessor());
-// // 添加 -proc:only 选项
-// List options = Arrays.asList("-proc:only");
-// JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options,
-// null, compilationUnits);
-// task.setProcessors(processors);
-//
-// boolean success = task.call();
-// if (success) {
-// System.out.println("Compilation and annotation processing completed successfully.");
-// } else {
-// System.out.println("Compilation and annotation processing failed.");
-// }
+ public static boolean compileAndSave(String sourceFile) {
+ // 获取系统 Java 编译器
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+
+ // 获取标准文件管理器
+ try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
+
+ // 设置编译输出目录
+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, List.of(new File("target" + File.separator + "classes")));
+
+ // 获取源文件
+ List javaFiles = List.of(new File(sourceFile));
+ Iterable extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(javaFiles);
+
+ // 创建编译任务
+ JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
+ // 执行编译任务
+ return task.call();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public static void compilerEntityTableDef(String actModulePath, String fileName, String entityPath, List javaPathList) {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
+ Iterable extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(
+ entityPath);
+// // 设置注解处理器
+ Iterable extends Processor> processors = List.of(new MybatisFlexProcessor());
+// // 添加 -proc:only 选项
+ List options = List.of("-proc:only");
+ JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options,
+ null, compilationUnits);
+ task.setProcessors(processors);
+ task.call();
+ compilationUnits = fileManager.getJavaFileObjects(
+ javaPathList.toArray(new String[0]));
+ // 需在entity之后加载
+ // 设置编译输出目录
+ fileManager.setLocation(StandardLocation.CLASS_OUTPUT, List.of(new File("target/classes")));
+
+ task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
+ String pathStr = actModulePath + File.separator + "entity" + File.separator + "table" + File.separator;
+ String filePathStr = pathStr + fileName + "EntityTableDef.java";
+ javaPathList.add(1, filePathStr);
+ boolean success = task.call();
+ if (success) {
+ System.out.println("Compilation and annotation processing completed successfully.");
+ String commPath = PathUtils.getUserDir() + File.separator + "com";
+ if (countFiles(new File(commPath)) <= 1) {
+ FileUtil.clean(commPath);
+ FileUtil.del(commPath);
+ }
+ } else {
+ System.out.println("Compilation and annotation processing failed.");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ private static int countFiles(File directory) {
+ File[] files = directory.listFiles();
+ if (files == null) {
+ return 0;
+ }
+
+ int count = 0;
+ for (File file : files) {
+ if (file.isFile()) {
+ count++;
+ } else if (file.isDirectory()) {
+ count += countFiles(file);
+ }
+ // If more than one file is found, no need to continue counting
+ if (count > 1) {
+ break;
+ }
+ }
+ return count;
}
}
diff --git a/src/main/java/com/cool/core/util/PathUtils.java b/src/main/java/com/cool/core/util/PathUtils.java
index 72bed3e..694611b 100644
--- a/src/main/java/com/cool/core/util/PathUtils.java
+++ b/src/main/java/com/cool/core/util/PathUtils.java
@@ -2,6 +2,7 @@ package com.cool.core.util;
import cn.hutool.core.io.file.PathUtil;
import com.cool.CoolApplication;
+import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -17,8 +18,21 @@ public class PathUtils {
}
public static String getModulesPath() {
- return getUserDir() + "/src/main/java/" + CoolApplication.class.getPackageName()
- .replace(".", "/") + "/modules";
+ return getUserDir() + File.separator + "src"+ File.separator + "main" + File.separator + "java" + File.separator + CoolApplication.class.getPackageName()
+ .replace(".", File.separator) + File.separator + "modules";
+ }
+
+ public static String getClassName(String filePath) {
+ // 定位 "src/main/java" 在路径中的位置
+ int srcMainJavaIndex = filePath.indexOf("src" + File.separator + "main" + File.separator + "java");
+ if (srcMainJavaIndex == -1) {
+ throw new IllegalArgumentException("File path does not contain 'src/main/java'");
+ }
+
+ // 提取 "src/main/java" 之后的路径
+ // 将文件分隔符替换为包分隔符
+ return filePath.substring(srcMainJavaIndex + ("src" + File.separator + "main" + File.separator + "java").length() + 1)
+ .replace(File.separator, ".").replace(".java", "");
}
/**
diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java
index fb07917..5927db6 100644
--- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java
+++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysMenuServiceImpl.java
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONObject;
+import com.cool.CoolApplication;
import com.cool.core.base.BaseServiceImpl;
import com.cool.core.base.ModifyEnum;
import com.cool.core.util.CompilerUtils;
@@ -147,24 +148,25 @@ public class BaseSysMenuServiceImpl extends BaseServiceImpl javaPathList = new ArrayList<>();
String modulesPath = PathUtils.getModulesPath();
// 创建的模块地址
String actModulePath = CompilerUtils.createModule(modulesPath, module);
- // 创建 controller
- CompilerUtils.createController(actModulePath, fileName, controller);
+ // 创建顺序不能调整,类加载的时候需按这个顺序加载,否则类找不到
// 创建 entity
String entityPath = CompilerUtils.createEntity(actModulePath, fileName, entity);
- // 创建 service
- CompilerUtils.createService(actModulePath, fileName, service);
- // 创建 serviceImpl
- CompilerUtils.createServiceImpl(actModulePath, fileName, serviceImpl);
+ javaPathList.add(entityPath);
// 创建 mapper
- CompilerUtils.createMapper(actModulePath, fileName, mapper);
- // 关闭springboot
- System.exit(0);
+ javaPathList.add(CompilerUtils.createMapper(actModulePath, fileName, mapper));
+ // 创建 service
+ javaPathList.add(CompilerUtils.createService(actModulePath, fileName, service));
+ // 创建 serviceImpl
+ javaPathList.add(CompilerUtils.createServiceImpl(actModulePath, fileName, serviceImpl));
+ // 创建 controller
+ javaPathList.add(CompilerUtils.createController(actModulePath, fileName, controller));
// 构建TableDef
- // CompilerUtils.compilerEntityTableDef(entityPath);
+ CompilerUtils.compilerEntityTableDef(actModulePath, fileName, entityPath, javaPathList);
// 重启
- // CoolApplication.restart();
+ CoolApplication.restart(javaPathList);
}
}
\ No newline at end of file