diff --git a/.gitignore b/.gitignore
index 6ff364a..9d9e6d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,6 @@
/PowerShell启动说明.md
/DEPLOYMENT.md
/ERROR_CAPTURE_GUIDE.md
-/*.sql
\ No newline at end of file
+/*.sql
+/JDK21_UPGRADE_NOTES.md
+/start-jdk21.sh
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 973930c..c74d1fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,17 +14,25 @@
org.springframework.boot
spring-boot-starter-parent
- 2.2.6.RELEASE
+ 2.7.18
- 1.8
- 1.8
- 1.8
+ 21
+ 21
+ 21
+ 21
true
2.17.1
1.2.9
1.12.0
+
+ 1.18.34
+ 3.5.16
+ 1.2.23
+ 3.5.7
+
+ 1.8.0
@@ -50,19 +58,36 @@
org.apache.shiro
shiro-spring
+
+
+ com.github.xiaoymin
+ knife4j-spring-boot-starter
+
+
+ io.springfox
+ springfox-swagger2
+
+
+ io.springfox
+ springfox-swagger-ui
+
+
+ io.springfox
+ springfox-boot-starter
+
com.alibaba
druid-spring-boot-starter
- 1.1.21
+ ${druid.version}
org.projectlombok
lombok
- 1.18.30
+ ${lombok.version}
provided
@@ -137,7 +162,7 @@
org.mybatis
mybatis
- 3.5.6
+ ${mybatis.version}
@@ -145,6 +170,37 @@
shiro-spring
${shiro.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ ${springdoc.version}
+
+
+
+ org.springdoc
+ springdoc-openapi-webmvc-core
+ ${springdoc.version}
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+ compile
+
+
+
+ com.github.xiaoymin
+ knife4j-annotations
+ 2.0.9
+ compile
+
devops-api-gd
@@ -152,6 +208,62 @@
org.springframework.boot
spring-boot-maven-plugin
+
+
+ --add-opens java.base/java.util=ALL-UNNAMED
+ --add-opens java.base/java.lang=ALL-UNNAMED
+ --add-opens java.base/java.lang.reflect=ALL-UNNAMED
+ --add-opens java.base/java.time=ALL-UNNAMED
+ --add-opens java.desktop/java.beans=ALL-UNNAMED
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ 21
+ 21
+ 21
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ --add-opens
+ java.base/java.util=ALL-UNNAMED
+ --add-opens
+ java.base/java.lang=ALL-UNNAMED
+ --add-opens
+ java.base/java.lang.reflect=ALL-UNNAMED
+ -Xlint:deprecation
+ -Xlint:unchecked
+ -Xlint:-options
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.2.5
+
+
+ --add-opens java.base/java.util=ALL-UNNAMED
+ --add-opens java.base/java.lang=ALL-UNNAMED
+ --add-opens java.base/java.lang.reflect=ALL-UNNAMED
+ --add-opens java.base/java.time=ALL-UNNAMED
+
+
diff --git a/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java b/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java
index 534883e..2ad01ba 100644
--- a/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java
+++ b/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java
@@ -54,6 +54,7 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A
log.info("====== 程 序:{} !", applicationName);
log.info("====== 版本号:{} ", version);
log.info("====== 描 述:{} ", description);
+ log.info("====== Java环境:{}", getJavaVersionInfo());
log.info("====== 接口文档路径:/doc.html,账号:admin、密码:123456。注:如果乱码请指定VM -Dfile.encoding=UTF-8");
log.info("====== Druid Monitor路径:/druid,账号:admin、密码:123456");
@@ -173,7 +174,7 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A
private static boolean isJava9OrHigher() {
try {
String version = System.getProperty("java.version");
- // Java 8: 1.8.x, Java 9+: 9.x, 10.x, 11.x, etc.
+ // Java 8: 1.8.x, Java 9+: 9.x, 10.x, 11.x, 21.x, etc.
if (version.startsWith("1.8")) {
return false;
}
@@ -186,7 +187,21 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A
} catch (Exception e) {
log.warn("解析Java版本失败: " + System.getProperty("java.version"), e);
}
- return false; // 默认认为是Java 8
+ return true; // JDK 21环境下默认为true
+ }
+
+ /**
+ * 获取当前Java版本信息
+ */
+ private static String getJavaVersionInfo() {
+ try {
+ String version = System.getProperty("java.version");
+ String vendor = System.getProperty("java.vendor");
+ String vmName = System.getProperty("java.vm.name");
+ return String.format("Java %s (%s - %s)", version, vendor, vmName);
+ } catch (Exception e) {
+ return "Java version unknown";
+ }
}
/**
diff --git a/src/main/java/com/chinaweal/youfool/devops/config/SpringDocOpenApiConfig.java b/src/main/java/com/chinaweal/youfool/devops/config/SpringDocOpenApiConfig.java
new file mode 100644
index 0000000..4274e53
--- /dev/null
+++ b/src/main/java/com/chinaweal/youfool/devops/config/SpringDocOpenApiConfig.java
@@ -0,0 +1,114 @@
+package com.chinaweal.youfool.devops.config;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.springdoc.core.GroupedOpenApi;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * SpringDoc OpenAPI 配置类 (替换SpringFox)
+ * @author itluck
+ */
+@Configuration
+@ConditionalOnProperty(value = "swagger.enable", havingValue = "true")
+public class SpringDocOpenApiConfig {
+
+ @Value("${applicationName}")
+ private String applicationName;
+
+ @Value("${version:1.0.0}")
+ private String version;
+
+ @Value("${description:DevOps运维管理系统}")
+ private String description;
+
+ @Value("${license:Apache 2.0}")
+ private String license;
+
+ /**
+ * 配置OpenAPI基本信息
+ */
+ @Bean
+ public OpenAPI customOpenAPI() {
+ return new OpenAPI()
+ .info(new Info()
+ .title(applicationName)
+ .description(description)
+ .version(version)
+ .contact(new Contact()
+ .name("chinaweal")
+ .url("https://www.chinaweal.com.cn")
+ .email(""))
+ .license(new License()
+ .name(license)
+ .url("https://www.chinaweal.com.cn")))
+ .components(new Components()
+ .addSecuritySchemes("token", new SecurityScheme()
+ .type(SecurityScheme.Type.APIKEY)
+ .in(SecurityScheme.In.HEADER)
+ .name("token")
+ .description("令牌")));
+ }
+
+ /**
+ * 组织架构模块API分组
+ */
+ @Bean
+ public GroupedOpenApi orgApi() {
+ return GroupedOpenApi.builder()
+ .group("组织架构")
+ .packagesToScan("com.chinaweal.youfool.devops.org")
+ .build();
+ }
+
+ /**
+ * 运维报障模块API分组
+ */
+ @Bean
+ public GroupedOpenApi devopsApi() {
+ return GroupedOpenApi.builder()
+ .group("运维报障")
+ .packagesToScan("com.chinaweal.youfool.devops.repair")
+ .build();
+ }
+
+ /**
+ * 基础环境模块API分组
+ */
+ @Bean
+ public GroupedOpenApi basisApi() {
+ return GroupedOpenApi.builder()
+ .group("基础环境")
+ .packagesToScan("com.chinaweal.youfool.devops.base")
+ .build();
+ }
+
+ /**
+ * WebSocket测试环境API分组
+ */
+ @Bean
+ public GroupedOpenApi websocketApi() {
+ return GroupedOpenApi.builder()
+ .group("WebSocket测试环境")
+ .packagesToScan("com.chinaweal.youfool.devops.websocket")
+ .build();
+ }
+
+ /**
+ * 领导分配模块API分组
+ */
+ @Bean
+ public GroupedOpenApi leaderAssignApi() {
+ return GroupedOpenApi.builder()
+ .group("领导分配")
+ .packagesToScan("com.chinaweal.youfool.devops.leaderassign")
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/chinaweal/youfool/devops/config/SwaggerKnife4j.java b/src/main/java/com/chinaweal/youfool/devops/config/SwaggerKnife4j.java
deleted file mode 100644
index ccb6a35..0000000
--- a/src/main/java/com/chinaweal/youfool/devops/config/SwaggerKnife4j.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package com.chinaweal.youfool.devops.config;
-
-import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.builders.ParameterBuilder;
-import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.builders.RequestHandlerSelectors;
-import springfox.documentation.schema.ModelRef;
-import springfox.documentation.service.ApiInfo;
-import springfox.documentation.service.Contact;
-import springfox.documentation.service.Parameter;
-import springfox.documentation.spi.DocumentationType;
-import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author itluck
- */
-@Configuration
-@EnableSwagger2
-@EnableKnife4j
-@ConditionalOnProperty(value = "swagger.enable", havingValue = "true")
-public class SwaggerKnife4j {
- @Value("${applicationName}")
- private String applicationName;
- @Value("${version}")
- private String version;
- @Value("${description}")
- private String description;
- @Value("${license}")
- private String license;
-
- @Bean("orgApi")
- public Docket orgApi() {
- ParameterBuilder tokenPar = new ParameterBuilder();
- List headers = new ArrayList<>();
- tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
- headers.add(tokenPar.build());
- return new Docket(DocumentationType.SWAGGER_2)
- .enable(true)
- .apiInfo(apiInfo())
- .groupName("组织架构")
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.chinaweal.youfool.devops.org"))
- .paths(PathSelectors.any())
- .build()
- .globalOperationParameters(headers);
- }
-
- @Bean("devopsApi")
- public Docket devopsApi() {
- //添加head参数start
- ParameterBuilder tokenPar = new ParameterBuilder();
- List headers = new ArrayList<>();
- tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
- headers.add(tokenPar.build());
- return new Docket(DocumentationType.SWAGGER_2)
- .enable(true)
- .apiInfo(apiInfo())
- .groupName("运维报障")
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.chinaweal.youfool.devops.repair"))
- .paths(PathSelectors.any())
- .build()
- .globalOperationParameters(headers);
- }
-
- @Bean("basisApi")
- public Docket basisApi() {
- //添加head参数start
- ParameterBuilder tokenPar = new ParameterBuilder();
- List headers = new ArrayList<>();
- tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
- headers.add(tokenPar.build());
- return new Docket(DocumentationType.SWAGGER_2)
- .enable(true)
- .apiInfo(apiInfo())
- .groupName("基础环境")
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.chinaweal.youfool.devops.base"))
- .paths(PathSelectors.any())
- .build()
- .globalOperationParameters(headers);
- }
-
- @Bean("websocketApi")
- public Docket websocketApi() {
- //添加head参数start
- ParameterBuilder tokenPar = new ParameterBuilder();
- List headers = new ArrayList<>();
- tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
- headers.add(tokenPar.build());
- return new Docket(DocumentationType.SWAGGER_2)
- .enable(true)
- .apiInfo(apiInfo())
- .groupName("WebSocket测试环境")
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.chinaweal.youfool.devops.websocket"))
- .paths(PathSelectors.any())
- .build()
- .globalOperationParameters(headers);
- }
-
-
- private ApiInfo apiInfo() {
- return new ApiInfoBuilder()
- .title(applicationName)
- .description(description)
- .termsOfServiceUrl("https://www.chinaweal.com.cn")
- .version(version)
- .contact(new Contact("chinaweal", "https://www.chinaweal.com.cn", ""))
- .license(license)
- .licenseUrl("https://www.chinaweal.com.cn")
- .build();
- }
-}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 2183f1a..19f9d8c 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -14,6 +14,9 @@ spring:
url: jdbc:postgresql://172.22.80.157:5432/devops_gd
username: devops_gd
password: ChinaWeal@2024
+ main:
+ # Spring Boot 2.7+新增:允许循环依赖(临时修复,后续需重构代码消除循环依赖)
+ allow-circular-references: true
file:
devopsDir: D:\chinaweal\gitea-code\youfool-project\youfool-devops\upload
@@ -32,6 +35,21 @@ applicationName: devOps
swagger:
enable: true
+
+# SpringDoc OpenAPI 配置 (替换SpringFox)
+springdoc:
+ api-docs:
+ enabled: true
+ path: /v3/api-docs
+ swagger-ui:
+ enabled: true
+ path: /swagger-ui.html
+ operations-sorter: alpha
+ tags-sorter: alpha
+
+version: "1.0.0"
+description: "DevOps运维管理系统API文档"
+license: "Apache 2.0"
# 错误日志配置
error-log:
# 是否启用错误日志文件写入功能
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 5489ceb..fd78042 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -32,3 +32,10 @@ dbWebhookKeys: 45d1bda2-c0b9-45c3-b640-be77f7a0726d,2eacc126-74d2-4360-a88e-369c
swagger:
enable: false
+
+# SpringDoc OpenAPI 配置 (生产环境禁用)
+springdoc:
+ api-docs:
+ enabled: false
+ swagger-ui:
+ enabled: false