修复优惠券模块

This commit is contained in:
2025-08-09 16:44:32 +08:00
parent d214e4b3cc
commit c93eeaa5e3
8 changed files with 77 additions and 40 deletions

View File

@@ -1,8 +1,8 @@
# Spring Bean 循环依赖修复报告 # Spring Bean 循环依赖修复报告 (完整版)
## 问题描述 ## 问题描述
应用启动时出现 `BeanCreationException` 错误,错误信息显示 应用启动时出现复杂的 `BeanCreationException` 错误,涉及多个Bean的循环依赖
``` ```
Error creating bean with name 'bszxBmController': Injection of resource dependencies failed; Error creating bean with name 'bszxBmController': Injection of resource dependencies failed;
@@ -18,7 +18,7 @@ Error creating bean with name 'cmsDesignServiceImpl': Injection of resource depe
## 根本原因分析 ## 根本原因分析
通过分析代码发现了两个主要的循环依赖问题 通过分析代码发现了复杂的循环依赖涉及多个层级的Bean相互依赖
### 1. 自我注入问题 ### 1. 自我注入问题
`CmsNavigationServiceImpl` 中存在自我注入: `CmsNavigationServiceImpl` 中存在自我注入:
@@ -34,14 +34,22 @@ public class CmsNavigationServiceImpl extends ServiceImpl<CmsNavigationMapper, C
} }
``` ```
### 2. 循环依赖问题 ### 2. 复杂的循环依赖
- `CmsNavigationServiceImpl` 依赖 `CmsDesignService` 发现了以下循环依赖关系:
**主要循环依赖链**:
```
BszxBmController → BszxBmService → CmsArticleService → CmsNavigationService → CmsDesignService → CmsNavigationService
```
**具体依赖关系**:
- `BszxBmController` 依赖 `BszxBmService``CmsArticleService`
- `BszxBmServiceImpl` 依赖 `CmsArticleService`
- `CmsArticleServiceImpl` 依赖 `CmsNavigationService`
- `CmsNavigationServiceImpl` 依赖 `CmsDesignService` 和自我注入 `CmsNavigationService`
- `CmsDesignServiceImpl` 依赖 `CmsNavigationService` - `CmsDesignServiceImpl` 依赖 `CmsNavigationService`
这形成了一个循环依赖链: 这形成了一个复杂的循环依赖网络导致Spring无法正确初始化这些Bean。
```
CmsNavigationServiceImpl → CmsDesignService → CmsDesignServiceImpl → CmsNavigationService → CmsNavigationServiceImpl
```
## 修复方案 ## 修复方案
@@ -66,17 +74,9 @@ final CmsNavigation parent = cmsNavigationService.getOne(new LambdaQueryWrapper<
final CmsNavigation parent = this.getOne(new LambdaQueryWrapper<CmsNavigation>()...); final CmsNavigation parent = this.getOne(new LambdaQueryWrapper<CmsNavigation>()...);
``` ```
### 修复2解决循环依赖问题 ### 修复2使用 @Lazy 注解打破循环依赖
**文件**: `src/main/java/com/gxwebsoft/cms/service/impl/CmsDesignServiceImpl.java` **文件1**: `src/main/java/com/gxwebsoft/cms/service/impl/CmsDesignServiceImpl.java`
**修复前**:
```java
@Resource
private CmsNavigationService cmsNavigationService;
```
**修复后**:
```java ```java
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
@@ -85,6 +85,33 @@ import org.springframework.context.annotation.Lazy;
private CmsNavigationService cmsNavigationService; private CmsNavigationService cmsNavigationService;
``` ```
**文件2**: `src/main/java/com/gxwebsoft/cms/service/impl/CmsArticleServiceImpl.java`
```java
import org.springframework.context.annotation.Lazy;
@Resource
@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 修复 ### 1. CmsNavigationServiceImpl.java 修复

View File

@@ -13,6 +13,7 @@ import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -34,6 +35,7 @@ public class BszxBmController extends BaseController {
@Resource @Resource
private BszxBmService bszxBmService; private BszxBmService bszxBmService;
@Resource @Resource
@Lazy
private CmsArticleService cmsArticleService; private CmsArticleService cmsArticleService;
@PreAuthorize("hasAuthority('bszx:bszxBm:list')") @PreAuthorize("hasAuthority('bszx:bszxBm:list')")

View File

@@ -24,6 +24,7 @@ import com.gxwebsoft.common.core.utils.ImageUtil;
import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -49,6 +50,7 @@ public class BszxBmServiceImpl extends ServiceImpl<BszxBmMapper, BszxBm> impleme
@Resource @Resource
private ConfigProperties config; private ConfigProperties config;
@Resource @Resource
@Lazy
private CmsArticleService cmsArticleService; private CmsArticleService cmsArticleService;
@Resource @Resource
private BszxClassService bszxClassService; private BszxClassService bszxClassService;

View File

@@ -20,6 +20,7 @@ import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.service.UserService; import com.gxwebsoft.common.system.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -52,6 +53,7 @@ public class CmsArticleController extends BaseController {
@Resource @Resource
private CmsArticleContentService articleContentService; private CmsArticleContentService articleContentService;
@Resource @Resource
@Lazy
private CmsNavigationService cmsNavigationService; private CmsNavigationService cmsNavigationService;
@Resource @Resource
private CmsModelService cmsModelService; private CmsModelService cmsModelService;

View File

@@ -17,6 +17,7 @@ import com.gxwebsoft.common.core.utils.AliYunSender;
import com.gxwebsoft.common.core.utils.JSONUtil; import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@@ -33,12 +34,12 @@ import java.util.Map;
@Service @Service
public class CmsArticleContentServiceImpl extends ServiceImpl<CmsArticleContentMapper, CmsArticleContent> implements CmsArticleContentService { public class CmsArticleContentServiceImpl extends ServiceImpl<CmsArticleContentMapper, CmsArticleContent> implements CmsArticleContentService {
@Resource @Resource
@Lazy
private CmsNavigationService cmsNavigationService; private CmsNavigationService cmsNavigationService;
@Resource @Resource
@Lazy
private CmsArticleService cmsArticleService; private CmsArticleService cmsArticleService;
@Resource @Resource
private CmsArticleContentService cmsArticleContentService;
@Resource
private CmsLangLogService cmsLangLogService; private CmsLangLogService cmsLangLogService;
@Override @Override
public PageResult<CmsArticleContent> pageRel(CmsArticleContentParam param) { public PageResult<CmsArticleContent> pageRel(CmsArticleContentParam param) {
@@ -139,7 +140,7 @@ public class CmsArticleContentServiceImpl extends ServiceImpl<CmsArticleContentM
target.setContent(article.getContent()); target.setContent(article.getContent());
System.out.println("target = " + target); System.out.println("target = " + target);
cmsArticleService.updateById(target); cmsArticleService.updateById(target);
cmsArticleContentService.update(new LambdaUpdateWrapper<CmsArticleContent>().eq(CmsArticleContent::getArticleId, target.getArticleId()).set(CmsArticleContent::getContent,target.getContent())); this.update(new LambdaUpdateWrapper<CmsArticleContent>().eq(CmsArticleContent::getArticleId, target.getArticleId()).set(CmsArticleContent::getContent,target.getContent()));
} }
}else { }else {
// 新增操作 // 新增操作
@@ -149,7 +150,7 @@ public class CmsArticleContentServiceImpl extends ServiceImpl<CmsArticleContentM
content.setArticleId(article.getArticleId()); content.setArticleId(article.getArticleId());
content.setContent(article.getContent()); content.setContent(article.getContent());
content.setTenantId(article.getTenantId()); content.setTenantId(article.getTenantId());
cmsArticleContentService.save(content); this.save(content);
} }
} }

View File

@@ -20,6 +20,7 @@ import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.service.UserService; import com.gxwebsoft.common.system.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -41,12 +42,11 @@ import static com.gxwebsoft.common.core.constants.ArticleConstants.CACHE_KEY_ART
@Service @Service
public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArticle> implements CmsArticleService { public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArticle> implements CmsArticleService {
@Resource @Resource
@Lazy
private CmsNavigationService cmsNavigationService; private CmsNavigationService cmsNavigationService;
@Resource @Resource
private CmsArticleContentService cmsArticleContentService; private CmsArticleContentService cmsArticleContentService;
@Resource @Resource
private CmsArticleContentService articleContentService;
@Resource
private UserService userService; private UserService userService;
@Resource @Resource
private CmsModelService cmsModelService; private CmsModelService cmsModelService;
@@ -122,7 +122,7 @@ public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArti
// article.setBanner(model.getBanner()); // article.setBanner(model.getBanner());
// } // }
// 附加文字内容 // 附加文字内容
CmsArticleContent content = articleContentService.getOne(new LambdaQueryWrapper<CmsArticleContent>().eq(CmsArticleContent::getArticleId, article.getArticleId()).last("limit 1")); CmsArticleContent content = cmsArticleContentService.getOne(new LambdaQueryWrapper<CmsArticleContent>().eq(CmsArticleContent::getArticleId, article.getArticleId()).last("limit 1"));
if (content != null) { if (content != null) {
article.setContent(content.getContent()); article.setContent(content.getContent());
} }
@@ -172,9 +172,9 @@ public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArti
content.setArticleId(article.getArticleId()); content.setArticleId(article.getArticleId());
content.setContent(article.getContent()); content.setContent(article.getContent());
content.setTenantId(article.getTenantId()); content.setTenantId(article.getTenantId());
articleContentService.save(content); cmsArticleContentService.save(content);
// 同步翻译并保存 // 同步翻译并保存
articleContentService.translate(article); cmsArticleContentService.translate(article);
return true; return true;
} }
} catch (Exception e) { } catch (Exception e) {
@@ -221,11 +221,11 @@ public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArti
String key = CACHE_KEY_ARTICLE + article.getArticleId(); String key = CACHE_KEY_ARTICLE + article.getArticleId();
redisUtil.delete(key); redisUtil.delete(key);
// 更新内容 // 更新内容
final boolean update = articleContentService.update(new LambdaUpdateWrapper<CmsArticleContent>().eq(CmsArticleContent::getArticleId, article.getArticleId()).set(CmsArticleContent::getContent, article.getContent())); final boolean update = cmsArticleContentService.update(new LambdaUpdateWrapper<CmsArticleContent>().eq(CmsArticleContent::getArticleId, article.getArticleId()).set(CmsArticleContent::getContent, article.getContent()));
if (update) { if (update) {
// 同步翻译并保存 // 同步翻译并保存
article.setIsUpdate(true); article.setIsUpdate(true);
articleContentService.translate(article); cmsArticleContentService.translate(article);
return true; return true;
} else { } else {
// 添加内容 // 添加内容
@@ -233,7 +233,7 @@ public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArti
content.setArticleId(article.getArticleId()); content.setArticleId(article.getArticleId());
content.setContent(article.getContent()); content.setContent(article.getContent());
content.setTenantId(article.getTenantId()); content.setTenantId(article.getTenantId());
articleContentService.save(content); cmsArticleContentService.save(content);
} }
return true; return true;
} }

View File

@@ -43,6 +43,7 @@ public class CmsDesignServiceImpl extends ServiceImpl<CmsDesignMapper, CmsDesign
@Lazy @Lazy
private CmsNavigationService cmsNavigationService; private CmsNavigationService cmsNavigationService;
@Resource @Resource
@Lazy
private CmsArticleContentService cmsArticleContentService; private CmsArticleContentService cmsArticleContentService;
@Override @Override

View File

@@ -16,6 +16,7 @@ import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.service.UserService; import com.gxwebsoft.common.system.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@@ -31,6 +32,7 @@ import java.util.List;
@Service @Service
public class CmsNavigationServiceImpl extends ServiceImpl<CmsNavigationMapper, CmsNavigation> implements CmsNavigationService { public class CmsNavigationServiceImpl extends ServiceImpl<CmsNavigationMapper, CmsNavigation> implements CmsNavigationService {
@Resource @Resource
@Lazy
private CmsDesignService cmsDesignService; private CmsDesignService cmsDesignService;
@Resource @Resource
private CmsModelService cmsModelService; private CmsModelService cmsModelService;