1

我在考虑我的一些服务。其中一些看起来像这样:

@Service
public class UserService {

   @Autowired
   UserDao dao;

   @Autowired 
   OtherService1 serv1;
   @Autowired 
   OtherService2 serv2;
   @Autowired 
   OtherService3 serv3;
   ....



}

我在想.. 如果这种将其他服务自动装配成单个服务的概念很常见,为什么不创建一个“主服务”:

@Service
public class MasterService {


   @Autowired 
   OtherService1 serv1;
   @Autowired 
   OtherService2 serv2;
   @Autowired 
   OtherService3 serv3;
   ...
   @Autowired 
   LastService servN;


}

并将此服务自动装配到所有服务中。

@Service
public class AnyService {

   @Autowired 
   MasterService masterSevice;
}

这样我们每个服务就不会有很多服务,但只有一个来统治它们。

提出两个问题:

1)由于 masterService 包含所有服务,我们在注入中有一个循环。我们能解决吗?

2) 如果问题 1 的答案是“是” - 这是“masterService”的好习惯吗?

4

4 回答 4

2

1) Spring 能够在很多情况下处理依赖循环,尤其是在不使用构造函数注入的情况下。

2)尽管如此。你应该绝对避免这种设计。它打破了良好架构的许多原则:

  • 组件应该只能根据需要访问尽可能少的其他组件。得墨忒耳定律
  • 关注点分离。服务不应同时处理业务逻辑和表示。
  • 抽象级别。服务不应同时处理数据的逻辑视图和持久性视图。

违反这些原则可能会导致不良情况,例如:

  • 无法遵循代码路径(单个请求将以难以理解的顺序通过 12 个服务,并且依赖于许多级别的条件逻辑)。
  • 很难知道哪些组件相互依赖。
  • 强耦合代码(更改低级服务将导致高级服务更改)。

您从这样的设计中获得的优势非常小(您只需避免一些@Autowired注释)并且不值得冒险。

于 2013-08-20T12:56:21.043 回答
1
  1. 为什么会有循环依赖?有一个服务包含所有其他服务,没有其他服务包含它。话虽如此,通过将依赖项设置为属性而不是构造函数 arg 可以轻松解决循环依赖项。

  2. 我不这么认为,声明一种层次结构(例如在端点中)是一种很好的模式,但是这种方式的优点是什么?没有它,您也可以自动装配您想要的每项服务。

于 2013-08-20T06:57:14.930 回答
0

1)MasterService不一定包含循环。如果是这样,那么您将遇到问题,并且首先不在循环中构造您的 bean 要简单得多。

2) 如果您要注入大量短期 bean,这可能会很有效,但这种方法的缺点是任何干预MasterService实例的人都可能搞砸其他 bean 的服务。您可以将其隐藏在 getter 方法后面,但将所有内容混为一谈通常不会带来太多好处。

相反,通常最好将相关服务组合在一起,可能是OtherService1OtherService2,并将它们放在一个接口上。这使得模拟测试变得更加容易,并将相关概念放在一起(最好在他们自己的 jars/modules 中)。

于 2013-08-20T06:58:54.547 回答
0

我以前没有遇到过这种模式(一个服务包含其他服务)。我经常看到和使用的是如下所示 -

*SpecificController1 --> SpecificService1 --> SpecificDao1

SpecificController2 --> SpecificService2 --> SpecificDao2

现在,如果SpecificService1需要SpecificService2中已有的某些功能,那么它只会引用SpecificService2

所以,我对上述模式有几个问题:

  1. MasterService 将如何使用?即任何需要任何服务的控制器(或任何人)都将首先使用 MasterService 来获取对实际服务的引用,或者 MasterService 将充当代表?
  2. 在什么场景下,你需要这样的设计,有什么优势?
于 2013-08-20T07:26:45.320 回答