最近想体验下最新版本的 SpringBoot,逛了下官网,发现 SpringBoot 目前最新版本已经是 2.6.4 了,版本更新确实够快的。之前的项目升级了 2.6.4 版本后发现有好多坑,不仅有循环依赖的问题,连 Swagger 都没法用了!今天给大家分享下升级过程,填一填这些坑!
一、聊聊 SpringBoot 版本
首先我们来聊聊 SpringBoot
的版本,目前最新版本是 2.6.4
版本,2.7.x
即将发布,2.4.x
及以下版本已经停止维护了,目前的主流版本应该是 2.5.x
和 2.6.x
。具体可以看下下面这张表。
二、开发中的坑
来找一个 SpringCloud
项目。
添加依赖
首先在 pom.xml
中修改 SpringBoot
的版本号,注意从 2.4.x
版本开始,SpringBoot
就不再使用 .RELEASE
后缀了。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
循环依赖
-
启动项目后,由于
SpringBoot
禁止了循环引用,我们来看第一个报错,securityConfig 和 umsAdminServiceImpl 循环引用了,具体日志如下:
-
具体来说就是我们的 SecurityConfig 引用了 UmsAdminService;
-
而 UmsAdminServiceImpl 又引用了 PasswordEncoder;
-
由于 SecurityConfig 继承了 WebSecurityConfigurerAdapter,而 Adapter 又引用了 PasswordEncoder,这样就导致了循环引用。
-
要解决这个问题其实很简单,你可以修改
application.yml
直接允许循环引用,不过这个方法有点粗暴,在没有其他方法的时候可以使用;
spring:
main:
allow-circular-references: true
-
其实循环引用主要是因为会导致
Spring
不知道该先创建哪个Bean
才会被禁用的,我们可以使用@Lazy
注解指定某个Bean
进行懒加载就可以优雅解决该问题,比如在 SecurityConfig 中懒加载 UmsAdminService。
启动出错 -
再次启动
SpringBoot
应用后会出现一个空指针异常,一看就是Swagger
问题,原来挺好用的Swagger
不能用了!
-
在
Swagger
的配置类中添加如下Bean
可以解决该问题;
/**
* Swagger2API文档的配置
*/
@Configuration
public class Swagger2Config {
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}
文档无法显示
- 再次启动后访问
Swagger
文档,会发现之前好好的文档也无法显示了,访问地址: http://localhost:8088/swagger-ui/
- 修改
application.yml
文件,MVC
默认的路径匹配策略为PATH_PATTERN_PARSER
,需要修改为ANT_PATH_MATCHER
;
spring:
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER
- 再次启动后发现
Swagger
已经可以正常使用了!
三、聊聊 Springfox
提到 Swagger
,我们一般在 SpringBoot
中集成的都是 springfox
给我们提供的工具库,看了下官网,该项目已经快两年没有发布新版本了。
再看下 Maven
仓库中的版本,依旧停留在之前的 3.0.0
版本。如果 springfox
再不出新版本的话,估计随着 SpringBoot
版本的更新,兼容性会越来越差的!
参考地址:https://github.com/springfox/springfox