类之间的循环依赖指的的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