首页 > 关于分层和循环注入的问题,求大神帮忙解答一下

关于分层和循环注入的问题,求大神帮忙解答一下

通常我们在做一套系统时,一个请求的流程大概是action(controller)->service->dao,这个流程很清晰,也很简单,但是在具体业务中我们可能需要不同的业务之间的配合使用,这时可能需要service中调用service。
例如AService中调用BService,BService中又调用CService,CService又调用AService,这样我们就造成了A中注入B,B中注入C,C中又注入A的循环注入情况,这时Spring在初始化时就出问题了。

在查询了一些资料中,基本上意见都是“这属于系统设计问题”,经过不断的思考,我想出一个解决办法,那就是我们在普通的三层设计中再添加一层(BusinessService),我们规定:

1,**Service层只面向单表(这里的单表指的是不注入其他service层,当然在写sql时仍然可以join其他表,不过返回结果就需要自定义一个dto来接收)**。
2,**若在service层只对数据库负责,要进行数据持久时,不校验数据的正确性,只校验数据是否为空,是否符合数据库的非空约束、是否符合数据库的索引约束等。**

若有比较复杂的业务(需要多个子业务支撑)时,我们在Business层中统一调用多个service层的方法,然后依次由BusinessService层进行组装和事务控制,举个例子:

我们现在有一个添加学生个业务,添加学生总共有3个子业务
   1,保存学生基本信息
   2,更新学生所在的班级学生数量
   3,更新学生所在的学校的学生总数

那我们只需要在StudentBusinessService中依次注入StudentService、ClassStudentCountService、SchoolStudentCountService,并在StudentBusinessService中的add方法内依次调用这三个子业务的对应方法即可。
如此,这样A->B-C->A 就变成了 A-B,A-C(A层为BusinessService层,B、C为service层,service层永远不会调用BusinessService层,从而打破了之前循环结构) 从而解决了之前的问题了

但是,随着业务的增长,之前在BusinessService中定义的方法可能成为更大的一个业务中的一个子业务了,
举个例子,

教师在从一个校区调到另一个校区,此时需要将该教师原有的学生全部加入到现在的校区中(**此处为业务规定,不做合理性解释**)

那么也很简单,我们需要在TeacherBusinessService中注入StudentBusinessService即可,然后调用StudentBusinessService的add方法,然后add方法会调用其他子业务,但是这样可能又回到了之前的A->B-C-A的模式了,随着业务的增长,很可能又会出现循环注入的问题。

我暂时还没想出更好的解决办法,不知各位是如何处理类似的问题的?


分层的设计理念,分多了,更细,维护起来,有点不便。分少了,结构混乱,不易维护。三层模型是经过检验的出来的结论。

例如AService中调用BService,BService中又调用CServiceCService又调用AService,这样我们就造成了A中注入BB中注入`C,C中又注入A的循环注入情况,这时Spring`在初始化时就出问题了

Spring在单例的场景下,是可以解决循环依赖的问题的,所以站在整个系统正确性角度上来看的话,那么如果系统中存在循环依赖,是不会对系统的正确性造成影响的

所以归根结底来看,这确实是系统设计上应该考虑的问题

具体可以参考系统中循环引用


首先,对于Spring中的循环引用是不会有问题的,而且循环引用在很多时候也是不可避免,很多设计模式实际上都存在着循环引用的情况。

其次,对于像StudentService只调用StudentDao的情况只是理想情况下出现的,实际场景下,一个Service肯定会调用其他Service来完成自身功能。若不希望存在循环引用的情况,那只能让Service依赖Dao(因为Dao之间是不会存在互相依赖的情况),但这样做会造成大量的代码冗余,粒度也过细。

最后,在业务实现中,循环引用是正常的,对于Spring的管理、事物的处理来说都不会产生问题。


我觉得这确实是系统设计问题,一般系统分层原则是,越是底层越细化,例如数据库的DAO基本是针对单个表的,越往上层越抽象化,比如某个Service可能会注入多个DAO来实现某个业务。
你提的问题应该就是Service没有按照职责划分清楚,比如StudentService应只能实现Student相关的业务,其它的业务应该不归它管理,因此在StudentService里面不应该调用ClassService或者SchoolService。
就如你所言的解决方案,Service层本身根据不同的业务职责是可以分成多个层,只要确保在同一层里面的Service不会互相引用(也不应该引用),复杂的业务需求应当由更上层的Service提供。
三层设计只是一个指导方针,你可以扩展成n层,这依赖你业务需求的复杂度。

【热门文章】
【热门文章】