抽象分层的Controller-Service-Repository 样式
对数据的处理实际会比较复杂,包括
- Validation:数据合法性校验,有些输入是可选的,有些是限定某些值,这些需要检查
- Alert:告警提示,对于数据的变化,可能需要发送邮件,消息或者移动短信
- 应用现有数据的变化:应用数据可能会出现关联的变化,例如一些统计信息。
- 数据保存。
我们不可能将这些都一股脑都放置在Controller中实现。我们需要进行抽象分层。
- 要将UI逻辑和业务逻辑分离,变更UI,无需变更业务逻辑代码。
- 要将数据存储(持久化)逻辑和业务逻辑分离。数据存储和储存介质有关,内存方式,文件方式,关系数据库,noSQL数据库有区别。
Controller-Service-Repository 样式样式和MVC不一样,不是强制的,Spring通过标记来实现。
@Repository提供持续化的逻辑,属于最底层,对数据存储进行读写,实现特定接口(数据操作),以便上层通过接口来使用它。仓库可以使用其他的仓库,但不应使用高层的Service或Controller。
@Service提供业务逻辑,位于仓库之上,可以使用其他Service和仓库,同样也实现特定的接口(事务处理)。我们也可以将其标记为@Component。
@Controller提供UI逻辑,使用Service,不使用其他Controller和仓库。
root application context
之前我们使用ServletContextConfiguration来配置DispatchServlet,配置限定在servlet容器内,配置如何接收和响应HTTP请求。如果我们创建SOAP或者RESTful服务,我们可以创建另一个DispatchServlet,有着不同的配置,例如无需ByteArrayHttpMessageConverter、StringHttpMessageConverter、FormHttpMessageConverter,无需ViewResolver、RequestToViewNameTranslator。
如果web app有多个UI,需要共享某些业务逻辑(service),这些service和仓库应该定制在root application contenxt中。由于UI和Cotnroller有关,这也是为何我们在root app contenxt中不扫描controller的缘故,也是为何在servlet Context配置中只扫描Contoller的原因。扫描是通过basePackages和filter(include已经exclude)来设置的。
下面是等价的,缺省useDefaultFilters为true,扫描所有的Component。
@ComponentScan(basePackages = "com.wrox.site")
@ComponentScan(
basePackages = "com.wrox.site",
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(value = Component.class,
type = FilterType.ANNOTATION)
)
我们可以设置自己的filter,如果useDefaultFilters = true,则在上面进行增加,如果是false,则重置。
相关链接: 我的Professional Java for Web Applications相关文章