首页 > 其他分享 >类之间的循环依赖,你头疼了吗?

类之间的循环依赖,你头疼了吗?

时间:2023-07-24 20:35:13浏览次数:30  
标签:头疼 依赖 userId 循环 user selectByUserId public

类之间的循环依赖指的的A依赖B,B也依赖A,这就出现循环依赖。如果是spring容器中的两个bean出现循环依赖,则在容器启动时,可能会报错,导致无法启动。

 

如果解决循环依赖?

首先要理清各类的职责,尤其是分层职责————相同层级不要相互调用,调用下级API。

下面是职责不清晰导致的循环依赖。解决方案是,调用下层方法。UserService和LoginAccountService是同一层服务,那么,他们在调用对方的数据时,应调用其下层的方法。例如:UserService#selectUserInfo在获取LoginAccount数据时,改为调用loginAccountMapper#selectByUserId。这样就解决了bean直接的循环依赖。

// -------------------------  UserService  ------------------------------------
@Service
public class UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private LoginAccountService loginAccountService;


    public UserVO selectUserInfo(int userId) {
        User user = userMapper.selectByUserId(userId);
        if (user == null) {
            throw new ResponseException("用户不存在");
        }
        UserVO userVO = BeanMapper.map(user, UserVO.class);
        LoginAccount loginAccount= loginAccountService.selectByUserId(userId);
        if (loginAccount!=null){
            userVO.setLoginAccount(loginAccount.getLoginAccount());
        }
        return userVO;
    }

    public void validUser(int userId) {
        User user = userMapper.selectByUserId(userId);
        if (user == null) {
            throw new ResponseException("用户不存在");
        }
        if (!"NORMAL".equalsIgnoreCase(user.getStatus())) {
            throw new ResponseException("用户已禁用");
        }
    }
}

// ---------------------------  LoginAccountService ----------------------------------
@Service
public class LoginAccountService {
    @Resource
    private UserService userService;
    @Resource
    private LoginAccountMapper loginAccountMapper;

    public LoginAccount login(String loginAccount, String password) {
        // 获取登陆账号
        LoginAccount entity = loginAccountMapper.selectByAccount(loginAccount);
        if (entity == null) {
            throw new ResponseException("账号不存在");
        }
        if (!password.equals(entity.getPassword())) {
            throw new ResponseException("用户密码错误");
        }
        userService.validUser(entity.getUserId());
        return entity;

    }

    public LoginAccount selectByUserId(int userId) {
        return loginAccountMapper.selectByUserId(userId);
    }
}
View Code

当然,上面的循环依赖,单从技术层面,加@Lasy是可以解决的,但还是应该从类的职责方面来进行改进。职责不清晰会带来诸多问题,绝不仅仅是重复依赖的问题。

 

还有一种情况,也是我今天碰到的一个情况。跟大家分享一下。
我们的中台channel服务,对接了数家银行通道。其中的一个YiLian通道有个特殊需求,在支付时需要对收款人进行报备,报备完成才可下发。见下图示意图,YiLianPayStrategy 有注入PayUserSignService,PayUserSignService有注入YiLianSignStrategy,YiLianSignStrategy有注入YiLianPayStrategy。 这就导致了YiLianPayStrategy 与YiLianSignStrategy的相互循环依赖。

 

这在企业应用开发中是个比较典型的正常案例。那么,如果解决这种循环依赖呢?
解决方案有二:
1. 不使用bean注入的方式,改为需要时才获取bean。


2. 使用spring的事件监听器,实现类之间的解耦。

 

标签:头疼,依赖,userId,循环,user,selectByUserId,public
From: https://www.cnblogs.com/buguge/p/17578264.html

相关文章

  • C语言分支与循环(7)--- do...while()循环
    一.do语句的语法do循环语句;while(表达式);我们可以发现do后面的循环语句一定会被执行一次,随后再去执行while()循环语句,去判断表达式,如果为真则返回do语句继续执行,若为假则不进入do语句循环,如以下代码:#include<stdio.h>intmain(void){ inti=0; do { printf("%d",i);......
  • Day08_for循环+print补充用法
    1.for循环和while循环取值: 2.for循环字典: 3.for循环字符串: 4.总结for循环和while循环的异同: 5.for循环控制循环次数:range() 6.for+break和for+else: 7.range(): 8.for+continue: 9.for循环嵌套: 10.print补充用法: ......
  • 简单理解:C语言中的分支和循环语句
    一、C语言中的循环语句while循环while(//条件语句){//语句块}执行的逻辑:在执行到while()这一行时,会根据条件语句的真和假来判断是否继续进行循环,若条件语句为真则继续循环,如果条件为假则结束循环。dowhile循环do{//语句块}while(条件语句);执行的逻辑:和while类似,但是要注......
  • 1.3 循环结构 参考代码
    P5722[深基4.例11]数列求和#include<cstdio>intmain(){intn;scanf("%d",&n);intsum=0;for(inti=1;i<=n;i++)sum+=i;printf("%d\n",sum);return0;}P5718[深基4.例2]找最小值#include<cs......
  • .net 6 依赖注入
    实现".NET6依赖注入"的步骤对于一个刚入行的小白来说,理解和实现".NET6依赖注入"可能会有些困惑。下面是一份简单的步骤列表,帮助你快速了解并实现这一功能。步骤概览步骤描述步骤1添加NuGet包步骤2实现依赖注入容器步骤3注册服务步骤4使用依......
  • 2-8 编写一个函数 rightrot(x, n),该函数返回将 x 循环右移(即从最右端 移出的位将从最
    ArchlinuxGCC13.1.1 202304292023-07-2319:59:05星期日 点击查看代码#include<stdio.h>#include<stdint.h>intrightrot(unsignedintx,intn){uint8_ttmp;while(n>0){tmp=(x&1)<<7;//0000000......
  • android 命令行 查看 so依赖
    Android命令行查看.so依赖在Android开发中,.so文件是一种动态链接库,用于存放与C/C++语言编写的代码,供Java层调用。在开发过程中,我们可能会遇到需要查看一个.so文件的依赖关系的情况。本文将介绍通过命令行查看.so依赖的方法,并提供相关示例代码。方法一:使用readelf命令在Linux系统......
  • springboot启动依赖冲突(log4j2)
    报错示例:LoggerFactoryisnotaLogbackLoggerContextbutLogbackison1.解决方案:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><......
  • MySQL之存储过程(循环)
    MySQL之存储过程变量@@是系统变量@是用户自定义的变量系统变量系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)。查看系统变量模板 SHOW[SESSION|GLOBAL]VARIABLES;--查看所有系统变量 SHOW[S......
  • python 循环往两个占位符
    Python循环往两个占位符循环是编程中常用的一种控制结构,它允许我们重复执行一段代码,达到简化代码和提高效率的目的。Python是一种高级编程语言,提供了多种循环结构,其中包括通过占位符循环的方法。在本文中,我们将介绍如何使用Python中的循环来填充两个占位符。什么是占位符?在......