为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

蝴蝶不菲 2019-03-13 17:14:35
通常我们在做一套系统时,一个请求的流程大概是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的模式了,随着业务的增长,很可能又会出现循环注入的问题。我暂时还没想出更好的解决办法,不知各位是如何处理类似的问题的?
查看完整描述

4 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

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

查看完整回答
反对 回复 2019-04-19
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

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

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

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

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


查看完整回答
反对 回复 2019-04-19
?
MMTTMM

TA贡献1869条经验 获得超4个赞

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

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

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


查看完整回答
反对 回复 2019-04-19
?
隔江千里

TA贡献1906条经验 获得超10个赞

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


查看完整回答
反对 回复 2019-04-19
  • 4 回答
  • 0 关注
  • 541 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号