SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

作者:MacroZheng 时间:2021-12-02 09:49:43 

前言

最近想体验下最新版本的SpringBoot,逛了下官网,发现SpringBoot目前最新版本已经是2.6.4了,版本更新确实够快的。之前的项目升级了2.6.4版本后发现有好多坑,不仅有循环依赖的问题,连Swagger都没法用了!今天给大家分享下升级过程,填一填这些坑!

SpringBoot实战电商项目mall(50k+star)地址:https://github.com/macrozheng/mall

首先我们来聊聊SpringBoot的版本,目前最新版本是2.6.4版本,2.7.x即将发布,2.4.x及以下版本已经停止维护了,目前的主流版本应该是2.5.x和2.6.x。具体可以看下下面这张表。

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

升级过程

下面我们将之前的mall-tiny-swagger项目升级下,看看到底有哪些坑,这些坑该如何解决!

添加依赖

首先在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循环引用了,具体日志如下;

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

具体来说就是我们的SecurityConfig引用了UmsAdminService;

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

而UmsAdminServiceImpl又引用了PasswordEncoder;

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

由于SecurityConfig继承了WebSecurityConfigurerAdapter,而Adapter又引用了PasswordEncoder,这样就导致了循环引用。

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

要解决这个问题其实很简单,你可以修改application.yml直接允许循环引用,不过这个方法有点粗暴,在没有其他方法的时候可以使用;

spring:
 main:
   allow-circular-references: true

其实循环引用主要是因为会导致Spring不知道该先创建哪个Bean才会被禁用的,我们可以使用@Lazy注解指定某个Bean进行懒加载就可以优雅解决该问题,比如在SecurityConfig中懒加载UmsAdminService。

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

启动出错

再次启动SpringBoot应用后会出现一个空指针异常,一看就是Swagger问题,原来挺好用的Swagger不能用了!

SpringBoot2.6.x升级后循环依赖及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/

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

修改application.yml文件,MVC默认的路径匹配策略为PATH_PATTERN_PARSER,需要修改为ANT_PATH_MATCHER;

spring:
 mvc:
   pathmatch:
     matching-strategy: ANT_PATH_MATCHER

再次启动后发现Swagger已经可以正常使用了!

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

聊聊springfox

提到Swagger,我们一般在SpringBoot中集成的都是springfox给我们提供的工具库,看了下官网,该项目已经快两年没有发布新版本了。

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

再看下Maven仓库中的版本,依旧停留在之前的3.0.0版本。如果springfox再不出新版本的话,估计随着SpringBoot版本的更新,兼容性会越来越差的!

SpringBoot2.6.x升级后循环依赖及Swagger无法使用问题

来源:https://blog.csdn.net/zhenghongcs/article/details/123652544

标签:SpringBoot2.6.x,循环依赖,Swagger
0
投稿

猜你喜欢

  • SpringBoot浅析Redis访问操作使用

    2022-09-26 02:09:18
  • SpringCloud如何创建一个服务提供者provider

    2023-08-01 01:56:33
  • Java实现级联下拉结构的示例代码

    2023-11-03 18:22:06
  • Maven打包jar生成javadoc文件和source文件代码实例

    2021-08-22 21:56:52
  • c#基础知识---委托,匿名函数,lambda

    2023-06-12 18:18:07
  • C#日期格式强制转换方法(推荐)

    2022-09-19 10:24:57
  • java计算两点间的距离方法总结

    2023-12-21 17:32:45
  • Java内部类及其特点的讲解

    2023-06-09 19:39:41
  • 教你怎么用Java数组和链表实现栈

    2023-10-29 08:13:57
  • 值得Java开发者关注的7款新工具

    2023-11-02 23:05:31
  • 接口签名怎么用Java实现

    2023-02-18 03:22:10
  • 解决@PathVariable对于特殊字符截断的问题

    2021-10-10 08:19:40
  • C#关于Func和Action委托的介绍详解

    2022-10-13 04:43:14
  • 辨析Java中的String与StringBuffer及StringBuilder字符串类

    2023-08-21 19:59:50
  • 基于C语言实现静态通讯录的示例代码

    2023-07-02 22:07:38
  • Java 前台加后台精品图书管理系统的实现

    2023-10-23 04:06:47
  • springboot配置https访问的方法

    2022-12-11 16:17:37
  • list集合去除重复对象的实现

    2022-10-16 23:02:42
  • Java控制台实现猜拳游戏

    2022-12-15 09:54:46
  • Flutter 底部弹窗如何实现多项选择

    2023-06-24 17:08:17
  • asp之家 软件编程 m.aspxhome.com