使用Spring+Spring MVC对服务层的设计思考

翻译 2012年03月26日 12:16:48
服务层在客户与系统两方面扮演了重要的角色。
对于客户,它暴露和封装了粗粒度的系统功能(用例)从而简化了使用。所谓粗粒度的方法是指那些高级别的方法,封装了广泛的工作流并避免了客户与系统许多小的交互。服务层是客户与系统交互的唯一途径,由于所有实现用例的POJO交互对于客户是隐蔽的,所以服务层要保持低耦合性。
对于系统,服务层方法代表工作的事务单元。这意味着当调用一个方法时,许多POJO及其交互就会在一个事务下执行。在服务层执行所有的工作使客户和系统的通信降到最少(实际上降到只有一个调用)。在一个事务众多的系统中,保持事务生命跨度最小是很重要的。另外一个好处是把事务移到单独一层易于集中进行事务配置。
在服务层的每个方法都应该是无状态的。就是说,每次调用服务方法都不会再实现服务接口的对象上创建状态。任何一个在服务对象上的方法调用都不应该假设之前的方法调用过它自己。整个方法调用的任何状态都应保持在领域模型中。
通常在MVC应用中,一个单独的服务层对象将处理执行多个并发线程,因而保持无状态是避免一个线程和另外一个线程冲突的唯一办法。这是事实带来了更简单的设计,因为它不需要服务对象缓冲池的要求。这种设计的性能好与实例池,因为它不需要对对象进入或者离开缓冲池进行检查管理。对每个服务对象使用单例同样也使内存使用降到最低。
该层尝试提供所有系统用例的封装。用例通常是一个事务工作单元,所以这两方面存在服务层中是有道理的。它同样使得为所有高层次的系统功能引用一层变得容易。
服务层之后的工作单元为最终用户和客户进入系统创建了一个单一入口点。将众多的客户通信机制放在一个单一的服务接口上现在变得很容易。例如,因为Spring具有远程功能,可以通过SOAP、RMI、HTTP上Java序列化,当然还有标准的XHTML来暴露相同的服务。它通过从传输机制或者用户界面解耦事务工作单元,支持代码复用和及其重要的DRY(不要重复自己)原则。
●举例
刚才提到,服务层给客户提供了一个接口,这种接口有非常粗粒度的方法,通常像代码清单1所以。


public interface AccountManager{
  void activeAccount(String accId);


  void unactiveAccount(String accId);


  Account getAccByUserName(String userName);
}


可以看出为什么这些方法被认为是粗粒度的。对于客户它使用了一个简单的调用完成一个单一的用例。对于细粒度的接口可知,细粒度接口可能需要许多不同的对象使用多次调用来完成一个用例。


public interface FindGraineAccountManager{
  Account findAccountByUsername(String userName);


  void setAccountToActive(Account acc);


  boolean accountAbleToBeActivated(Account acc);


  void sendActivationEmail(Account acc, Mailer mailer);
}


上述例子中,交给了客户过多的责任。方法调用的正确次序如何?如果失败了会发生什么?我们无法保证对每个调用使用的是同一个account实例。这种细粒度接口将使客户过于紧密耦合到用例实现的方式上。
在客户是远程的环境下,粗粒度接口是一种很重要的设计元素。序列化不是一种廉价的操作,因而每次调用服务层至多序列化一次,这一点很重要。即使系统中的客户在同一虚拟机内,要分离系统关注,是解耦及测试更容易进行时,该层扮演着至关重要的角色。


●依赖
服务层依赖于领域模型和持久层上,它结合并协助数据库访问对象非的调用。服务层绝不能依赖试图或者Web层。
值得注意的是,通常该层不必依赖于框架特定的代码或者基础构造代码,如事务管理。Spring框架爱显示引入系统的方面做得很好,这样代码便能保持高解耦性。


●Spring对服务层的支持
Spring框架不提供用于实现服务层业务方面的任何接口或类。不必惊讶,因为服务层是针对具体的应用程序的。
Spring并非定义业务接口而是有助于编程模型。一般来说,Spring框架的ApplicationContext将服务实例注入到Web控制器。当确定需要的时候,Spring会提供一些服务(比如事务管理、性能检测甚至缓冲池)来增强服务层。


●小结
为了系统交互,服务层提供了无状态、粗粒度的接口给客户使用。服务层的每种方法一般代表一个用例,同时也是一个事务工作单元。
使用服务层同样保持了系统和客户的第耦合性。它降低了用户所需的调用数量,使系统使用更方便。在远程环境中,这便大大提高了性能。

SpringMVC的层:DAO、Service、Controller、View

Controller层:负责具体业务模块流程的控制,即调用Service层的接口来控制业务流程。负责url映射(action)。Dao层:负责数据持久化,与数据库进行联络的任务都封装在其中,Dao层的...
  • huangxiaozuo
  • huangxiaozuo
  • 2017年05月04日 20:43
  • 1721

SpringMVC构建REST接口:第六篇 服务层实现

服务层,是控制层和数据库持久层之间的纽带,对数据进行具体的处理。在这一层,最基本的要求就是对数据库的CURD处理以及事物处理。 一、服务层接口编写        在com.jiahe.rest.d...
  • lxhjh
  • lxhjh
  • 2013年05月23日 12:46
  • 3414

springmvc+mybatis整合service层

在整合完dao层后,下一步就是service层的整合。这里顺道说一下,一个框架的搭建,最好是从底层往上开始搭建,至于这样做的好处,就请在实战中慢慢体会吧。 一、编写service 首先需要创建serv...
  • Sunking_Yin
  • Sunking_Yin
  • 2016年09月30日 16:41
  • 2261

spring+mybatis通用dao层、service层的一些个人理解与实现

1、现在的绝大多数web应用,通常都以action、service、dao三层去组织代码,这样划分结构很清晰,分工明确 2、一般情况下,我们会把事务控制在service层。 3、action和dao层...
  • lj402159806
  • lj402159806
  • 2017年01月13日 17:32
  • 5604

springMVC中controller层调用service层的方式

springmvc 中普通类调用注解service层 的方式除了 1.自动注入外:  @Autowired UserService userService; 2.还可以这样: ...
  • gooooooal
  • gooooooal
  • 2016年10月18日 16:15
  • 4350

spring service层配置

spring-service.xml
  • yzllz001
  • yzllz001
  • 2017年02月01日 16:21
  • 1848

dao层和service层

dao层中已经有操作数据库的方法了,为什么还要service层去封装?有什么好处? 首先解释面上意思,service是业务层,dao是数据访问层。 呵呵,这个问题我曾经也有过,记得以前刚学编程的时候...
  • LFhappypain
  • LFhappypain
  • 2015年05月14日 10:40
  • 2624

spring三层示例controller层,service层示例,dao层示例

Spring框架提倡面向接口编程,所以在写以下类时,最好能先写好接口,让以下的类去实现接口 1.Spring框架中controller层示例 package org.tarena.note...
  • fanlulu2015
  • fanlulu2015
  • 2015年12月17日 14:42
  • 3254

SPringMVC各层浅析

Entity层:通过创建实体类来实现创建数据库中表的功能; Repository层:是对数据库中表的具体操作功能的实现(个人理解其实就是书写SQL语句的地方,不知道理解正确与否) ...
  • Stephen_90
  • Stephen_90
  • 2016年06月06日 00:30
  • 3124

利用Spring MVC搭建REST Service

之前写过一篇 利用JAX-RS快速开发RESTful 服务 今天来看下spring-mvc框架如何实现类似的功能:  一、pom.xml 1 xml version="1....
  • a258831020
  • a258831020
  • 2015年10月12日 17:35
  • 1102
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用Spring+Spring MVC对服务层的设计思考
举报原因:
原因补充:

(最多只允许输入30个字)