spring boot 2.6.x 集成swagger3 启动报错解决方案
spring boot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
swagger starter
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
swagger 配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.ArrayList;
@Configuration
// swagger3 更新了注解
@EnableOpenApi
public class SwaggerConfig {
//配置Swagger的Docket的bean实例
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());//配置Swagger信息
}
//配置Swagger信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//设置文档标题(API名称)
.title("title")
//文档描述
.description("desc")
//版本号
.version("1.0")
.build();
}
}
解决启动报错
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 自定义BeanPostProcessor
*/
@Configuration
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {
@Autowired
private DefaultListableBeanFactory defaultListableBeanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
handleWebMvcRequestHandlerProvider(beanName, bean);
return bean;
}
private void handleWebMvcRequestHandlerProvider(String beanName, Object bean) {
// 处理swagger 在spring boot2.6以上不可用的问题
boolean modify = (bean instanceof WebMvcRequestHandlerProvider ||
bean instanceof WebFluxRequestHandlerProvider) &&
defaultListableBeanFactory.containsBean(beanName);
if (modify) {
// 修改属性
try {
Field handlerMappingsField = bean.getClass().getDeclaredField("handlerMappings");
ReflectUtils.makeAccessible(handlerMappingsField);
List<RequestMappingInfoHandlerMapping> handlerMappings =
(List<RequestMappingInfoHandlerMapping>) handlerMappingsField.get(bean);
List<RequestMappingInfoHandlerMapping> tmpHandlerMappings = handlerMappings.stream()
.filter(mapping -> Objects.isNull(mapping.getPatternParser())).collect(Collectors.toList());
handlerMappings.clear();
handlerMappings.addAll(tmpHandlerMappings);
} catch (Exception e) {
log.warn("修改WebMvcRequestHandlerProvider的属性:handlerMappings出错,可能导致swagger不可用", e);
}
}
}
}