SpringBoot 循环依赖

Posted KLAPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot 循环依赖相关的知识,希望对你有一定的参考价值。

什么是循环依赖

循环依赖是指在Spring Boot 应用程序中,两个或多个类之间存在彼此依赖的情况,形成一个循环依赖链。当一个类在初始化时需要另一个类的实例,而另一个类又需要第一个类的实例时,就会出现循环依赖问题。

发生情况:

循环依赖是指两个或更多的组件之间存在着互相依赖的关系。在Spring Boot应用程序中,循环依赖通常是由以下几种情况引起的:

  • 构造函数循环依赖: 两个或更多的组件在它们的构造函数中互相依赖。
  • 属性循环依赖: 两个或更多的组件在它们的属性中互相依赖。
  • 方法循环依赖: 两个或更多的组件在它们的方法中互相依赖。

解决方法:

Spring Boot提供了一些解决循环依赖的方法:

  • (1)构造函数注入: 在构造函数中注入依赖项,而不是在属性中注入。
  • public class A 
        private B b;

        public A(B b) 
            this.b = b;
        


    public class B 
        private A a;

        public B(A a) 
            this.a = a;
        
  • Setter注入: 使用setter方法注入依赖项,而不是在构造函数中注入。
  • 延迟注入: 使用@Lazy注解延迟加载依赖项。
  • @Autowired注解的required属性: 将required属性设置为false,以避免出现循环依赖问题。
  • @DependsOn注解: 使用@DependsOn注解指定依赖项的加载顺序,以避免出现循环依赖问题

SpringBoot 2.6.0发布:禁止循环依赖,还有哪些实用的更新?

点击关注公众号,实用技术文章及时了解

Spring Boot 2.6.0已经正式发布,快看看作了哪些升级。

1、禁止了循环依赖

循环依赖问题一直困扰大家,也是面试常问题目之一,对循环依赖不了解的可以看这篇:Spring高频面试题:如何解决循环依赖问题

Spring Boot 2.6.0之后,如果程序中存在循环依赖问题,启动上就会失败,报错:

┌─────┐
|  a (field private com.zhiyin.TestB com.zhiyin.TestA.b)
↑     ↓
|  b (field private com.zhiyin.TestA com.zhiyin.TestB.a)
└─────┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

如果程序设计非常合理,完全避免了循环依赖,是最完美的。如果实在不能,Spring Boot也提供了折中解决办法,在报错信息中已经明示:

As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

需要我们在配置文件application.properties里加上这个属性:

spring.main.allow-circular-references = true

程序依然可以正常启动。

2、新增自定义脱敏规则

Spring Boot 2.6.0 支持/env端点和configprops配置属性的自定义脱敏,自定义SanitizingFunction类型的Bean即可实现,如下:

@Bean
public SanitizingFunction pwdSanitizingFunction() 
    return data -> 
        org.springframework.core.env.PropertySource<?> propertySource = data.getPropertySource();
        String key = data.getKey();
        
        // 仅对redis.properties里面的某些key做脱敏
        if (propertySource.getName().contains("redis.properties")) 
            if (key.equals("redis.pwd")) 
                return data.withValue(SANITIZED_VALUE);
            
        
        return data;
    ;

对于部分数据脱敏,这个改进非常灵活,很有用。

3、Redis自动开启连接池

在2.6.0之前的版本,配置Redis时是否启用连接池是由使用者指定,2.6.0之后是默认开启,如果需要关闭,则需要配置:

spring.redis.jedis.pool.enabled = false

或者

spring.redis.lettuce.pool.enabled = false

说明Spring Boot支持大家使用Redis连接池。

4、支持使用WebTestClient来测试Spring MVC

开发人员可以使用 WebTestClient 在模拟环境中测试程序,只需要在Mock环境中使用 @AutoConfigureMockMvc 注释,就可以轻松注入 WebTestClient。,省去编写测试程序。

5、默认使用全新匹配策略

请求路径与 Spring MVC 处理映射匹配的默认策略已从AntPathMatcher更改为PathPatternParser。你可以设置spring.mvc.pathmatch.matching-strategyant-path-matcher来改变它。

2.6.0之前:

public static class Pathmatch 
 private MatchingStrategy matchingStrategy = 
               MatchingStrategy.ANT_PATH_MATCHER;

2.6.0之后:

public static class Pathmatch 
 private MatchingStrategy matchingStrategy = 
               MatchingStrategy.PATH_PATTERN_PARSER;

两者差异上:PathPattern去掉了Ant字样,但保持了很好的向下兼容性:除了不支持将**写在path中间之外,其它的匹配规则从行为上均保持和AntPathMatcher一致,并且还新增了强大的*pathVariable的支持。

6、增强了/info管理端点,加上了Java运行时信息

如下:


  "java": 
    "vendor": "BellSoft",
    "version": "17",
    "runtime": 
      "name": "OpenJDK Runtime Environment",
      "version": "17+35-LTS"
    ,
    "jvm": 
      "name": "OpenJDK 64-Bit Server VM",
      "vendor": "BellSoft",
      "version": "17+35-LTS"
    
  

7、其他变化

  • Servlet应用现在支持在Cookie中添加SameSite。

  • 支持在主端口或管理端口上配置健康组。

  • 在 Spring Boot 2.4 中弃用的类、方法和属性已在此版本中删除。

  • 支持 Log4j2 复合配置

  • 支持构建信息属性排除

另外需要注意的是,Spring Boot每年会在5月份和11月份发布两个中型版本,每个中型版本提供1年的免费支持,那也就意味着2.4.x已经停止了版本停止(免费)支持。不过对本次版本更新点有所了解即可,等待下次大版本更新再去学,一更新马上用新的实在学不动~~

参考:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6.0-Configuration-Changelog

推荐

主流Java进阶技术(学习资料分享)

Java面试题宝典

加入Spring技术开发社区

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!

以上是关于SpringBoot 循环依赖的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 2.6.0发布:禁止循环依赖,还有哪些实用的更新?

Springboot依赖打包分离及第三方包

解决SpringBoot集成分页插件pagehelper出现的循环依赖问题

解决SpringBoot集成分页插件pagehelper出现的循环依赖问题

解决SpringBoot集成分页插件pagehelper出现的循环依赖问题

解决SpringBoot集成分页插件pagehelper出现的循环依赖问题