春天的服务层 - 自动装配所有服务

时间:2013-08-20 06:44:35

标签: spring service autowired service-layer

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

@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 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

  • 组件应该只能访问所需的其他组件。 Demeter's Law
  • 关注点分离。服务不应同时处理业务逻辑和表示。
  • 抽象水平。服务不应该同时处理数据的逻辑视图和它的持久性视图。

违反这些原则可能会导致以下情况:

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

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

答案 2 :(得分:0)

1)MasterService不一定包含循环。如果确实如此,那么你将遇到问题,而且首先不在循环中构造你的bean会更简单。

2)如果您注入大量短命的bean,这可能会有效,但这种方法的缺点是,任何插入MasterService实例的人都可以搞砸了其他豆子。你可以把它隐藏在getter方法之后,但把所有东西放在一起通常不会带来太多好处。

相反,通常最好将相关的服务组合在一起,可能是OtherService1OtherService2,并将它们放在接口上。这使得对测试的模拟变得更加容易并将相关概念保持在一起(理想情况下在他们自己的jar /模块中)。

答案 3 :(得分:0)

之前我没有遇到过这样的模式(一个服务包含其他服务)。 我经常看到和使用的是下面的内容 -

* SpecificController1 - > SpecificService1 - > SpecificDao1

SpecificController2 - > SpecificService2 - > SpecificDao2

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

所以,我对上述模式的问题很少:

  1. 如何使用MasterService?即任何需要任何服务的控制器(或任何人)将首先使用MasterService来获取对实际服务的引用,或者MasterService将作为代表?
  2. 在什么情况下,你需要这样的设计,有什么优势?