🎉 解决升级底层组件后产生的兼容性问题

This commit is contained in:
smallchill 2025-07-02 23:36:40 +08:00
parent 8139c89007
commit a2150877fe
8 changed files with 201 additions and 12 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -27,7 +27,6 @@ import org.springframework.util.StringUtils;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 项目启动器搞定环境变量问题
@ -88,9 +87,9 @@ public class BladeApplication {
// 同时存在devtestprod环境时
throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]");
}
String startJarPath = BladeApplication.class.getResource("/").getPath().split("!")[0];
String startJarPath = Objects.requireNonNull(BladeApplication.class.getResource("/")).getPath().split("!")[0];
String activePros = joinFun.apply(activeProfileList.toArray());
System.out.println(String.format("----启动中,读取到的环境变量:[%s]jar地址:[%s]----", activePros, startJarPath));
System.out.printf("----启动中,读取到的环境变量:[%s]jar地址:[%s]----%n", activePros, startJarPath);
Properties props = System.getProperties();
props.setProperty("spring.application.name", appName);
props.setProperty("spring.profiles.active", profile);
@ -102,15 +101,15 @@ public class BladeApplication {
props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true");
props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION);
props.setProperty("spring.main.allow-bean-definition-overriding", "true");
props.setProperty("spring.cloud.nacos.config.prefix", NacosConstant.NACOS_CONFIG_PREFIX);
props.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
props.setProperty("spring.cloud.sentinel.transport.dashboard", SentinelConstant.SENTINEL_ADDR);
props.setProperty("spring.cloud.alibaba.seata.tx-service-group", appName.concat(NacosConstant.NACOS_GROUP_SUFFIX));
props.setProperty("spring.config.import", String.join(",", NacosConstant.dataId(), NacosConstant.dataId(profile), NacosConstant.dataId(appName, profile)));
props.setProperty("nacos.logging.default.config.enabled", "false");
// 加载自定义组件
List<LauncherService> launcherList = new ArrayList<>();
ServiceLoader.load(LauncherService.class).forEach(launcherList::add);
SpringApplicationBuilder finalBuilder = builder;
launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).collect(Collectors.toList())
launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).toList()
.forEach(launcherService -> launcherService.launcher(finalBuilder, appName, profile));
return finalBuilder;
}
@ -122,7 +121,7 @@ public class BladeApplication {
*/
public static boolean isLocalDev() {
String osName = System.getProperty("os.name");
return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equals(osName.toUpperCase()));
return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equalsIgnoreCase(osName));
}
}

View File

@ -22,6 +22,16 @@ package org.springblade.core.launch.constant;
*/
public interface NacosConstant {
/**
* optional
*/
String OPTIONAL = "optional";
/**
* nacos
*/
String NACOS = "nacos";
/**
* nacos 地址
*/
@ -57,6 +67,25 @@ public interface NacosConstant {
*/
String NACOS_CONFIG_GROUP = "DEFAULT_GROUP";
/**
* 服务默认加载的配置
*
* @return dataId
*/
static String dataId() {
return OPTIONAL + ":" + NACOS + ":" + NACOS_CONFIG_PREFIX + "." + NACOS_CONFIG_FORMAT;
}
/**
* 服务默认加载的配置
*
* @param profile 环境变量
* @return dataId
*/
static String dataId(String profile) {
return OPTIONAL + ":" + NACOS + ":" + NACOS_CONFIG_PREFIX + "-" + profile + "." + NACOS_CONFIG_FORMAT;
}
/**
* 构建服务对应的 dataId
*
@ -77,7 +106,7 @@ public interface NacosConstant {
* @return dataId
*/
static String dataId(String appName, String profile, String format) {
return appName + "-" + profile + "." + format;
return OPTIONAL + ":" + NACOS + ":" + appName + "-" + profile + "." + format;
}
}

View File

@ -18,7 +18,6 @@ package org.springblade.core.loadbalancer.props;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import java.util.ArrayList;
import java.util.List;
@ -30,7 +29,6 @@ import java.util.List;
*/
@Getter
@Setter
@RefreshScope
@ConfigurationProperties(BladeLoadBalancerProperties.PROPERTIES_PREFIX)
public class BladeLoadBalancerProperties {
public static final String PROPERTIES_PREFIX = "blade.loadbalancer";

View File

@ -0,0 +1,159 @@
/*
* Copyright © 2017-2023 Knife4j(xiaoymin@foxmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.xiaoymin.knife4j.spring.extension;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.github.xiaoymin.knife4j.core.conf.ExtensionsConstants;
import com.github.xiaoymin.knife4j.core.conf.GlobalConstants;
import com.github.xiaoymin.knife4j.spring.configuration.Knife4jProperties;
import com.github.xiaoymin.knife4j.spring.configuration.Knife4jSetting;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.models.OpenAPI;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RestController;
import java.lang.annotation.Annotation;
import java.util.*;
import java.util.stream.Collectors;
/**
* 增强扩展属性支持
*
* @author <a href="xiaoymin@foxmail.com">xiaoymin@foxmail.com</a>
* 2022/12/11 22:40
* @since 4.1.0
*/
@Slf4j
@AllArgsConstructor
public class Knife4jOpenApiCustomizer implements GlobalOpenApiCustomizer {
final Knife4jProperties knife4jProperties;
final SpringDocConfigProperties properties;
@Override
public void customise(OpenAPI openApi) {
log.debug("Knife4j OpenApiCustomizer");
if (knife4jProperties.isEnable()) {
Knife4jSetting setting = knife4jProperties.getSetting();
OpenApiExtensionResolver openApiExtensionResolver = new OpenApiExtensionResolver(setting, knife4jProperties.getDocuments());
// 解析初始化
openApiExtensionResolver.start();
Map<String, Object> objectMap = new HashMap<>();
objectMap.put(GlobalConstants.EXTENSION_OPEN_SETTING_NAME, setting);
objectMap.put(GlobalConstants.EXTENSION_OPEN_MARKDOWN_NAME, openApiExtensionResolver.getMarkdownFiles());
openApi.addExtension(GlobalConstants.EXTENSION_OPEN_API_NAME, objectMap);
addOrderExtension(openApi);
}
}
/**
* 往OpenAPI内tags字段添加x-order属性
*
* @param openApi openApi
*/
private void addOrderExtension(OpenAPI openApi) {
if (CollectionUtils.isEmpty(properties.getGroupConfigs())) {
return;
}
// 获取包扫描路径
Set<String> packagesToScan =
properties.getGroupConfigs().stream()
.map(SpringDocConfigProperties.GroupConfig::getPackagesToScan)
.filter(toScan -> !CollectionUtils.isEmpty(toScan))
.flatMap(List::stream)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(packagesToScan)) {
return;
}
// 扫描包下被ApiSupport注解的RestController Class
Set<Class<?>> classes =
packagesToScan.stream()
.map(packageToScan -> scanPackageByAnnotation(packageToScan, RestController.class))
.flatMap(Set::stream)
.filter(clazz -> clazz.isAnnotationPresent(ApiSupport.class))
.collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(classes)) {
// ApiSupport oder值存入tagSortMap<Tag.name,ApiSupport.order>
Map<String, Integer> tagOrderMap = new HashMap<>();
classes.forEach(
clazz -> {
Tag tag = getTag(clazz);
if (Objects.nonNull(tag)) {
ApiSupport apiSupport = clazz.getAnnotation(ApiSupport.class);
tagOrderMap.putIfAbsent(tag.name(), apiSupport.order());
}
});
// 往openApi tags字段添加x-order增强属性
if (openApi.getTags() != null) {
openApi
.getTags()
.forEach(
tag -> {
if (tagOrderMap.containsKey(tag.getName())) {
tag.addExtension(
ExtensionsConstants.EXTENSION_ORDER, tagOrderMap.get(tag.getName()));
}
});
}
}
}
private Tag getTag(Class<?> clazz) {
// 从类上获取
Tag tag = clazz.getAnnotation(Tag.class);
if (Objects.isNull(tag)) {
// 从接口上获取
Class<?>[] interfaces = clazz.getInterfaces();
if (ArrayUtils.isNotEmpty(interfaces)) {
for (Class<?> interfaceClazz : interfaces) {
Tag anno = interfaceClazz.getAnnotation(Tag.class);
if (Objects.nonNull(anno)) {
tag = anno;
break;
}
}
}
}
return tag;
}
private Set<Class<?>> scanPackageByAnnotation(
String packageName, final Class<? extends Annotation> annotationClass) {
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(annotationClass));
Set<Class<?>> classes = new HashSet<>();
for (BeanDefinition beanDefinition : scanner.findCandidateComponents(packageName)) {
try {
Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
classes.add(clazz);
} catch (ClassNotFoundException ignore) {
}
}
return classes;
}
}

View File

@ -15,7 +15,6 @@
*/
package org.springblade.core.swagger;
import net.dreamlu.mica.auto.annotation.AutoService;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.launch.service.LauncherService;
import org.springframework.boot.builder.SpringApplicationBuilder;
@ -28,7 +27,6 @@ import java.util.Properties;
*
* @author Chill
*/
@AutoService(LauncherService.class)
public class SwaggerLauncherServiceImpl implements LauncherService {
@Override
public void launcher(SpringApplicationBuilder builder, String appName, String profile) {

View File

@ -0,0 +1 @@
org.springblade.core.swagger.SwaggerLauncherServiceImpl

View File

@ -390,6 +390,11 @@
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.9</version>
</dependency>
<!-- protostuff -->
<dependency>
<groupId>io.protostuff</groupId>