Skip to content

【Bug】应用启动失败:RedisCenterImpl 的 @Async 导致与 MachineCenterImpl / AppScrollRestartServiceImpl 的循环依赖无法解析(BeanCurrentlyInCreationException) #387

Description

@Hungerdream

环境

  • CacheCloud 3.4(在 main 分支同样可复现)
  • Spring Boot 2.2.9.RELEASE / Spring Framework 5.2.x / Java 8

现象

Web 应用启动即失败,抛出:

org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'redisCenter':
Requested bean is currently in creation: Is there an unresolvable circular reference?

根因分析

MachineCenterImplAppScrollRestartServiceImpl 都通过 @Autowired 注入了 RedisCenter 的实现 RedisCenterImpl

关键点:RedisCenterImpl 上存在 @Async 注解的方法(如 findInstancePatternKeys,返回 java.util.concurrent.Future,见 RedisCenterImpl.java:912)。@Async 要求 Spring 在 bean 完全初始化之后才为其生成异步代理(AsyncAnnotationBeanPostProcessor 处理)。

这导致该循环引用无法用 Spring 的“早期引用(early reference)”机制消解:

  • 循环中的其他 bean 拿到的是 redisCenter 的半成品(原始对象),而容器最终放入的是异步代理;
  • 代理必须在 bean 完全创建后才能生成,因此该循环在结构上“无法解析(unresolvable)”。

修复方案

在两个注入点加 @Lazy(注入懒加载代理占位符以打破循环,已验证有效):

cachecloud-web/src/main/java/com/sohu/cache/machine/impl/MachineCenterImpl.java

+import org.springframework.context.annotation.Lazy;
...
     @Autowired
+    @Lazy
     private RedisCenter redisCenter;

cachecloud-web/src/main/java/com/sohu/cache/web/service/impl/AppScrollRestartServiceImpl.java

+import org.springframework.context.annotation.Lazy;
...
     @Autowired
+    @Lazy
     private RedisCenter redisCenter;

main 分支对应行:MachineCenterImpl.java:79AppScrollRestartServiceImpl.java:72

复现步骤

  1. 按官方文档编译部署(profile=open,MySQL 已就绪)
  2. 启动 web 应用
  3. 启动日志即报上述异常

建议

除上述 @Lazy 最小修复外,也可考虑重构 MachineCenterImpl / AppScrollRestartServiceImplRedisCenter 之间的依赖,从根本上消除循环。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions