From c93eeaa5e357506a0f1f36fb5d97267836072b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sat, 9 Aug 2025 16:44:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BC=98=E6=83=A0=E5=88=B8?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring_bean_circular_dependency_fix.md | 71 +++++++++++++------ .../bszx/controller/BszxBmController.java | 2 + .../bszx/service/impl/BszxBmServiceImpl.java | 2 + .../cms/controller/CmsArticleController.java | 2 + .../impl/CmsArticleContentServiceImpl.java | 9 +-- .../service/impl/CmsArticleServiceImpl.java | 16 ++--- .../service/impl/CmsDesignServiceImpl.java | 1 + .../impl/CmsNavigationServiceImpl.java | 2 + 8 files changed, 71 insertions(+), 34 deletions(-) diff --git a/spring_bean_circular_dependency_fix.md b/spring_bean_circular_dependency_fix.md index f57f109..b5e4512 100644 --- a/spring_bean_circular_dependency_fix.md +++ b/spring_bean_circular_dependency_fix.md @@ -1,24 +1,24 @@ -# Spring Bean 循环依赖修复报告 +# Spring Bean 循环依赖修复报告 (完整版) ## 问题描述 -应用启动时出现 `BeanCreationException` 错误,错误信息显示: +应用启动时出现复杂的 `BeanCreationException` 错误,涉及多个Bean的循环依赖: ``` -Error creating bean with name 'bszxBmController': Injection of resource dependencies failed; -nested exception is org.springframework.beans.factory.BeanCreationException: -Error creating bean with name 'bszxBmServiceImpl': Injection of resource dependencies failed; -nested exception is org.springframework.beans.factory.BeanCreationException: -Error creating bean with name 'cmsArticleServiceImpl': Injection of resource dependencies failed; -nested exception is org.springframework.beans.factory.BeanCreationException: -Error creating bean with name 'cmsNavigationServiceImpl': Injection of resource dependencies failed; -nested exception is org.springframework.beans.factory.BeanCreationException: +Error creating bean with name 'bszxBmController': Injection of resource dependencies failed; +nested exception is org.springframework.beans.factory.BeanCreationException: +Error creating bean with name 'bszxBmServiceImpl': Injection of resource dependencies failed; +nested exception is org.springframework.beans.factory.BeanCreationException: +Error creating bean with name 'cmsArticleServiceImpl': Injection of resource dependencies failed; +nested exception is org.springframework.beans.factory.BeanCreationException: +Error creating bean with name 'cmsNavigationServiceImpl': Injection of resource dependencies failed; +nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cmsDesignServiceImpl': Injection of resource dependencies failed ``` ## 根本原因分析 -通过分析代码发现了两个主要的循环依赖问题: +通过分析代码发现了复杂的循环依赖链,涉及多个层级的Bean相互依赖: ### 1. 自我注入问题 在 `CmsNavigationServiceImpl` 中存在自我注入: @@ -28,21 +28,29 @@ Error creating bean with name 'cmsDesignServiceImpl': Injection of resource depe public class CmsNavigationServiceImpl extends ServiceImpl implements CmsNavigationService { @Resource private CmsNavigationService cmsNavigationService; // 自我注入! - + // 在方法中使用 final CmsNavigation parent = cmsNavigationService.getOne(...); } ``` -### 2. 循环依赖问题 -- `CmsNavigationServiceImpl` 依赖 `CmsDesignService` -- `CmsDesignServiceImpl` 依赖 `CmsNavigationService` +### 2. 复杂的循环依赖链 +发现了以下循环依赖关系: -这形成了一个循环依赖链: +**主要循环依赖链**: ``` -CmsNavigationServiceImpl → CmsDesignService → CmsDesignServiceImpl → CmsNavigationService → CmsNavigationServiceImpl +BszxBmController → BszxBmService → CmsArticleService → CmsNavigationService → CmsDesignService → CmsNavigationService ``` +**具体依赖关系**: +- `BszxBmController` 依赖 `BszxBmService` 和 `CmsArticleService` +- `BszxBmServiceImpl` 依赖 `CmsArticleService` +- `CmsArticleServiceImpl` 依赖 `CmsNavigationService` +- `CmsNavigationServiceImpl` 依赖 `CmsDesignService` 和自我注入 `CmsNavigationService` +- `CmsDesignServiceImpl` 依赖 `CmsNavigationService` + +这形成了一个复杂的循环依赖网络,导致Spring无法正确初始化这些Bean。 + ## 修复方案 ### 修复1:解决自我注入问题 @@ -66,17 +74,18 @@ final CmsNavigation parent = cmsNavigationService.getOne(new LambdaQueryWrapper< final CmsNavigation parent = this.getOne(new LambdaQueryWrapper()...); ``` -### 修复2:解决循环依赖问题 - -**文件**: `src/main/java/com/gxwebsoft/cms/service/impl/CmsDesignServiceImpl.java` +### 修复2:使用 @Lazy 注解打破循环依赖 -**修复前**: +**文件1**: `src/main/java/com/gxwebsoft/cms/service/impl/CmsDesignServiceImpl.java` ```java +import org.springframework.context.annotation.Lazy; + @Resource +@Lazy private CmsNavigationService cmsNavigationService; ``` -**修复后**: +**文件2**: `src/main/java/com/gxwebsoft/cms/service/impl/CmsArticleServiceImpl.java` ```java import org.springframework.context.annotation.Lazy; @@ -85,6 +94,24 @@ import org.springframework.context.annotation.Lazy; private CmsNavigationService cmsNavigationService; ``` +**文件3**: `src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java` +```java +import org.springframework.context.annotation.Lazy; + +@Resource +@Lazy +private CmsArticleService cmsArticleService; +``` + +**文件4**: `src/main/java/com/gxwebsoft/bszx/controller/BszxBmController.java` +```java +import org.springframework.context.annotation.Lazy; + +@Resource +@Lazy +private CmsArticleService cmsArticleService; +``` + ## 修复详情 ### 1. CmsNavigationServiceImpl.java 修复 diff --git a/src/main/java/com/gxwebsoft/bszx/controller/BszxBmController.java b/src/main/java/com/gxwebsoft/bszx/controller/BszxBmController.java index 9d55988..995c6fb 100644 --- a/src/main/java/com/gxwebsoft/bszx/controller/BszxBmController.java +++ b/src/main/java/com/gxwebsoft/bszx/controller/BszxBmController.java @@ -13,6 +13,7 @@ import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.system.entity.User; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; +import org.springframework.context.annotation.Lazy; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -34,6 +35,7 @@ public class BszxBmController extends BaseController { @Resource private BszxBmService bszxBmService; @Resource + @Lazy private CmsArticleService cmsArticleService; @PreAuthorize("hasAuthority('bszx:bszxBm:list')") diff --git a/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java b/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java index 1b73248..c52f9a0 100644 --- a/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java +++ b/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java @@ -24,6 +24,7 @@ import com.gxwebsoft.common.core.utils.ImageUtil; import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageResult; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -49,6 +50,7 @@ public class BszxBmServiceImpl extends ServiceImpl impleme @Resource private ConfigProperties config; @Resource + @Lazy private CmsArticleService cmsArticleService; @Resource private BszxClassService bszxClassService; diff --git a/src/main/java/com/gxwebsoft/cms/controller/CmsArticleController.java b/src/main/java/com/gxwebsoft/cms/controller/CmsArticleController.java index 1f77365..5da719a 100644 --- a/src/main/java/com/gxwebsoft/cms/controller/CmsArticleController.java +++ b/src/main/java/com/gxwebsoft/cms/controller/CmsArticleController.java @@ -20,6 +20,7 @@ import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.service.UserService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; +import org.springframework.context.annotation.Lazy; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; @@ -52,6 +53,7 @@ public class CmsArticleController extends BaseController { @Resource private CmsArticleContentService articleContentService; @Resource + @Lazy private CmsNavigationService cmsNavigationService; @Resource private CmsModelService cmsModelService; diff --git a/src/main/java/com/gxwebsoft/cms/service/impl/CmsArticleContentServiceImpl.java b/src/main/java/com/gxwebsoft/cms/service/impl/CmsArticleContentServiceImpl.java index e94ddc6..d39ffe6 100644 --- a/src/main/java/com/gxwebsoft/cms/service/impl/CmsArticleContentServiceImpl.java +++ b/src/main/java/com/gxwebsoft/cms/service/impl/CmsArticleContentServiceImpl.java @@ -17,6 +17,7 @@ import com.gxwebsoft.common.core.utils.AliYunSender; import com.gxwebsoft.common.core.utils.JSONUtil; import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -33,12 +34,12 @@ import java.util.Map; @Service public class CmsArticleContentServiceImpl extends ServiceImpl implements CmsArticleContentService { @Resource + @Lazy private CmsNavigationService cmsNavigationService; @Resource + @Lazy private CmsArticleService cmsArticleService; @Resource - private CmsArticleContentService cmsArticleContentService; - @Resource private CmsLangLogService cmsLangLogService; @Override public PageResult pageRel(CmsArticleContentParam param) { @@ -139,7 +140,7 @@ public class CmsArticleContentServiceImpl extends ServiceImpl().eq(CmsArticleContent::getArticleId, article.getArticleId()).last("limit 1")); if (content != null) { article.setContent(content.getContent()); } @@ -172,9 +172,9 @@ public class CmsArticleServiceImpl extends ServiceImpl().eq(CmsArticleContent::getArticleId, article.getArticleId()).set(CmsArticleContent::getContent, article.getContent())); + final boolean update = cmsArticleContentService.update(new LambdaUpdateWrapper().eq(CmsArticleContent::getArticleId, article.getArticleId()).set(CmsArticleContent::getContent, article.getContent())); if (update) { // 同步翻译并保存 article.setIsUpdate(true); - articleContentService.translate(article); + cmsArticleContentService.translate(article); return true; } else { // 添加内容 @@ -233,7 +233,7 @@ public class CmsArticleServiceImpl extends ServiceImpl implements CmsNavigationService { @Resource + @Lazy private CmsDesignService cmsDesignService; @Resource private CmsModelService cmsModelService;