Skip to content

Commit fceaa7a

Browse files
committed
feat:【framework 框架】兼容 knife4j 4.5.0 版本,升级 spring boot 到 3.4.8
1 parent caa7500 commit fceaa7a

File tree

31 files changed

+191
-36
lines changed

31 files changed

+191
-36
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
4444
<!-- maven-surefire-plugin 暂时无法通过 bom 的依赖读取(兼容老版本 IDEA 2024 及以前版本) -->
4545
<lombok.version>1.18.38</lombok.version>
46-
<spring.boot.version>3.4.5</spring.boot.version>
46+
<spring.boot.version>3.4.8</spring.boot.version>
4747
<mapstruct.version>1.6.3</mapstruct.version>
4848
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4949
</properties>

yudao-dependencies/pom.xml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
<revision>2025.08-SNAPSHOT</revision>
1818
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
1919
<!-- 统一依赖管理 -->
20-
<spring.boot.version>3.4.5</spring.boot.version>
20+
<!-- TODO @芋艿:spring boot 3.5.4 和 spring cloud 当前版本不兼容,需要适配 -->
21+
<spring.boot.version>3.4.8</spring.boot.version>
2122
<spring.cloud.version>2024.0.1</spring.cloud.version>
2223
<spring.cloud.alibaba.version>2023.0.3.2</spring.cloud.alibaba.version>
2324
<!-- Web 相关 -->
24-
<springdoc.version>2.8.3</springdoc.version>
25-
<knife4j.version>4.6.0</knife4j.version>
25+
<springdoc.version>2.8.9</springdoc.version>
26+
<knife4j.version>4.5.0</knife4j.version>
2627
<!-- DB 相关 -->
2728
<druid.version>1.2.24</druid.version>
2829
<mybatis.version>3.5.19</mybatis.version>
@@ -45,7 +46,7 @@
4546
<lock4j.version>2.2.7</lock4j.version>
4647
<!-- 监控相关 -->
4748
<skywalking.version>9.0.0</skywalking.version>
48-
<spring-boot-admin.version>3.4.5</spring-boot-admin.version>
49+
<spring-boot-admin.version>3.4.7</spring-boot-admin.version>
4950
<opentracing.version>0.33.0</opentracing.version>
5051
<!-- Test 测试相关 -->
5152
<podam.version>8.0.2.RELEASE</podam.version>
@@ -178,19 +179,25 @@
178179
</dependency>
179180

180181
<dependency>
181-
<groupId>com.github.xingfudeshi</groupId> <!-- TODO 芋艿:https://github.com/xiaoymin/knife4j/issues/874 -->
182+
<groupId>com.github.xiaoymin</groupId>
182183
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
183184
<version>${knife4j.version}</version>
185+
<exclusions>
186+
<exclusion>
187+
<groupId>org.springdoc</groupId>
188+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
189+
</exclusion>
190+
</exclusions>
184191
</dependency>
185192
<dependency>
186193
<groupId>org.springdoc</groupId>
187-
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
194+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
188195
<version>${springdoc.version}</version>
189196
</dependency>
190197
<dependency>
191198
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 UI:knife4j【网关专属】 -->
192199
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
193-
<version>4.5.0</version> <!-- TODO 芋艿:等 4.5.0 => 4.6.0 -->
200+
<version>${knife4j.version}</version>
194201
</dependency>
195202

196203
<!-- DB 相关 -->

yudao-framework/yudao-common/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
<dependency>
6262
<groupId>org.springdoc</groupId>
63-
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
63+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
6464
<scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 -->
6565
</dependency>
6666

yudao-framework/yudao-spring-boot-starter-web/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@
4646
</dependency>
4747

4848
<dependency>
49-
<groupId>com.github.xingfudeshi</groupId>
49+
<groupId>com.github.xiaoymin</groupId>
5050
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
5151
</dependency>
5252
<dependency>
5353
<groupId>org.springdoc</groupId>
54-
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
54+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
5555
</dependency>
5656

5757
<!-- RPC 远程调用相关 -->
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package cn.iocoder.yudao.framework.swagger.config;
2+
3+
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
4+
import com.github.xiaoymin.knife4j.core.conf.ExtensionsConstants;
5+
import com.github.xiaoymin.knife4j.core.conf.GlobalConstants;
6+
import com.github.xiaoymin.knife4j.spring.configuration.Knife4jProperties;
7+
import com.github.xiaoymin.knife4j.spring.configuration.Knife4jSetting;
8+
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
9+
import io.swagger.v3.oas.annotations.tags.Tag;
10+
import io.swagger.v3.oas.models.OpenAPI;
11+
import lombok.extern.slf4j.Slf4j;
12+
import org.apache.commons.lang3.ArrayUtils;
13+
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
14+
import org.springdoc.core.properties.SpringDocConfigProperties;
15+
import org.springframework.beans.factory.config.BeanDefinition;
16+
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
17+
import org.springframework.context.annotation.Configuration;
18+
import org.springframework.context.annotation.Primary;
19+
import org.springframework.core.type.filter.AnnotationTypeFilter;
20+
import org.springframework.util.CollectionUtils;
21+
import org.springframework.web.bind.annotation.RestController;
22+
23+
import java.lang.annotation.Annotation;
24+
import java.util.*;
25+
import java.util.stream.Collectors;
26+
27+
/**
28+
* 增强扩展属性支持
29+
*
30+
* 参考 <a href="https://github.com/xiaoymin/knife4j/issues/913">Spring Boot 3.4 以上版本 /v3/api-docs 解决接口报错,依赖修复</a>
31+
*
32+
* @since 4.1.0
33+
* @author <a href="[email protected]">[email protected]</a>
34+
* 2022/12/11 22:40
35+
*/
36+
@Primary
37+
@Configuration
38+
@Slf4j
39+
public class Knife4jOpenApiCustomizer extends com.github.xiaoymin.knife4j.spring.extension.Knife4jOpenApiCustomizer
40+
implements GlobalOpenApiCustomizer {
41+
42+
final Knife4jProperties knife4jProperties;
43+
final SpringDocConfigProperties properties;
44+
45+
public Knife4jOpenApiCustomizer(Knife4jProperties knife4jProperties, SpringDocConfigProperties properties) {
46+
super(knife4jProperties,properties);
47+
this.knife4jProperties = knife4jProperties;
48+
this.properties = properties;
49+
}
50+
51+
@Override
52+
public void customise(OpenAPI openApi) {
53+
if (knife4jProperties.isEnable()) {
54+
Knife4jSetting setting = knife4jProperties.getSetting();
55+
OpenApiExtensionResolver openApiExtensionResolver = new OpenApiExtensionResolver(setting, knife4jProperties.getDocuments());
56+
// 解析初始化
57+
openApiExtensionResolver.start();
58+
Map<String, Object> objectMap = new HashMap<>();
59+
objectMap.put(GlobalConstants.EXTENSION_OPEN_SETTING_NAME, setting);
60+
objectMap.put(GlobalConstants.EXTENSION_OPEN_MARKDOWN_NAME, openApiExtensionResolver.getMarkdownFiles());
61+
openApi.addExtension(GlobalConstants.EXTENSION_OPEN_API_NAME, objectMap);
62+
addOrderExtension(openApi);
63+
}
64+
}
65+
66+
/**
67+
* 往 OpenAPI 内 tags 字段添加 x-order 属性
68+
*
69+
* @param openApi openApi
70+
*/
71+
private void addOrderExtension(OpenAPI openApi) {
72+
if (CollectionUtils.isEmpty(properties.getGroupConfigs())) {
73+
return;
74+
}
75+
// 获取包扫描路径
76+
Set<String> packagesToScan =
77+
properties.getGroupConfigs().stream()
78+
.map(SpringDocConfigProperties.GroupConfig::getPackagesToScan)
79+
.filter(toScan -> !CollectionUtils.isEmpty(toScan))
80+
.flatMap(List::stream)
81+
.collect(Collectors.toSet());
82+
if (CollectionUtils.isEmpty(packagesToScan)) {
83+
return;
84+
}
85+
// 扫描包下被 ApiSupport 注解的 RestController Class
86+
Set<Class<?>> classes = packagesToScan.stream()
87+
.map(packageToScan -> scanPackageByAnnotation(packageToScan, RestController.class))
88+
.flatMap(Set::stream)
89+
.filter(clazz -> clazz.isAnnotationPresent(ApiSupport.class))
90+
.collect(Collectors.toSet());
91+
if (!CollectionUtils.isEmpty(classes)) {
92+
// ApiSupport oder 值存入 tagSortMap<Tag.name,ApiSupport.order>
93+
Map<String, Integer> tagOrderMap = new HashMap<>();
94+
classes.forEach(clazz -> {
95+
Tag tag = getTag(clazz);
96+
if (Objects.nonNull(tag)) {
97+
ApiSupport apiSupport = clazz.getAnnotation(ApiSupport.class);
98+
tagOrderMap.putIfAbsent(tag.name(), apiSupport.order());
99+
}
100+
});
101+
// 往 openApi tags 字段添加 x-order 增强属性
102+
if (openApi.getTags() != null) {
103+
openApi.getTags().forEach(tag -> {
104+
if (tagOrderMap.containsKey(tag.getName())) {
105+
tag.addExtension(ExtensionsConstants.EXTENSION_ORDER, tagOrderMap.get(tag.getName()));
106+
}
107+
});
108+
}
109+
}
110+
}
111+
112+
private Tag getTag(Class<?> clazz) {
113+
// 从类上获取
114+
Tag tag = clazz.getAnnotation(Tag.class);
115+
if (Objects.isNull(tag)) {
116+
// 从接口上获取
117+
Class<?>[] interfaces = clazz.getInterfaces();
118+
if (ArrayUtils.isNotEmpty(interfaces)) {
119+
for (Class<?> interfaceClazz : interfaces) {
120+
Tag anno = interfaceClazz.getAnnotation(Tag.class);
121+
if (Objects.nonNull(anno)) {
122+
tag = anno;
123+
break;
124+
}
125+
}
126+
}
127+
}
128+
return tag;
129+
}
130+
131+
private Set<Class<?>> scanPackageByAnnotation(String packageName, final Class<? extends Annotation> annotationClass) {
132+
ClassPathScanningCandidateComponentProvider scanner =
133+
new ClassPathScanningCandidateComponentProvider(false);
134+
scanner.addIncludeFilter(new AnnotationTypeFilter(annotationClass));
135+
Set<Class<?>> classes = new HashSet<>();
136+
for (BeanDefinition beanDefinition : scanner.findCandidateComponents(packageName)) {
137+
try {
138+
Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
139+
classes.add(clazz);
140+
} catch (ClassNotFoundException ignore) {
141+
}
142+
}
143+
return classes;
144+
}
145+
146+
}

yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2424
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2525
import org.springframework.context.annotation.Bean;
26+
import org.springframework.context.annotation.Import;
2627
import org.springframework.context.annotation.Primary;
2728
import org.springframework.http.HttpHeaders;
2829

@@ -46,6 +47,7 @@
4647
@ConditionalOnClass({OpenAPI.class})
4748
@EnableConfigurationProperties(SwaggerProperties.class)
4849
@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true) // 设置为 false 时,禁用
50+
@Import(Knife4jOpenApiCustomizer.class)
4951
public class YudaoSwaggerAutoConfiguration {
5052

5153
// ========== 全局 OpenAPI 配置 ==========

yudao-module-ai/yudao-module-ai-server/src/main/resources/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ springdoc:
5959
default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
6060

6161
knife4j:
62-
enable: false # TODO 芋艿:需要关闭增强,具体原因见:https://github.com/xiaoymin/knife4j/issues/874
62+
enable: true
6363
setting:
6464
language: zh_cn
6565

yudao-module-bpm/yudao-module-bpm-api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<!-- Web 相关 -->
2626
<dependency>
2727
<groupId>org.springdoc</groupId> <!-- 接口文档:使用最新版本的 Swagger 模型 -->
28-
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
28+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
2929
<scope>provided</scope>
3030
</dependency>
3131

yudao-module-bpm/yudao-module-bpm-server/src/main/resources/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ springdoc:
5454
default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
5555

5656
knife4j:
57-
enable: false # TODO 芋艿:需要关闭增强,具体原因见:https://github.com/xiaoymin/knife4j/issues/874
57+
enable: true
5858
setting:
5959
language: zh_cn
6060

yudao-module-crm/yudao-module-crm-server/src/main/resources/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ springdoc:
5454
default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
5555

5656
knife4j:
57-
enable: false # TODO 芋艿:需要关闭增强,具体原因见:https://github.com/xiaoymin/knife4j/issues/874
57+
enable: true
5858
setting:
5959
language: zh_cn
6060

0 commit comments

Comments
 (0)