SpringBoot项目结构
为什么要写这篇
近来,学习了关于Spring或Spring Boot项目目录结构划分和代码分层,很多小伙伴表示网上下载下来的开源项目看不懂,项目结构和代码分层看得很蒙,不知道应该以一个什么样的思路去学习和吸收别人的项目。
先看看阿里是怎么约定的
我印象中,以前在看《阿里巴巴Java开发手册》时,好像有关于工程结构和应用分层相关的内容,于是我回翻了一下,果然有:
按这本书上说的,一般分为如下几层:
- 开放接口层:可直接封装 Service 接口暴露成 RPC 接口;通过 Web 封装成 http 接口;网关控制层等。
- 终端显示层:各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染,JS 渲染,JSP 渲染,移动端展示等。
- Web 层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
- Service 层:相对具体的业务逻辑服务层。
- Manager 层:通用业务处理层,它有如下特征
1)对第三方平台封装的层,预处理返回结果及转化异常信息,适配上层接口。
2)对 Service 层通用能力的下沉,如缓存方案、中间件通用处理。
3)与 DAO 层交互,对多个 DAO 的组合复用。 - DAO 层:数据访问层,与底层 MySQL、Oracle、Hbase、OceanBase 等进行数据交互。
- 第三方服务:包括其它部门 RPC 服务接口,基础平台,其它公司的 HTTP 接口,如淘宝开放平台、支付宝付款服务、高德地图服务等。
- 外部接口:外部(应用)数据存储服务提供的接口,多见于数据迁移场景中。
由于书中的篇幅关系,它这地方讲得比较笼统了,估计初学者看了还是会懵,所以接下来结合实际项目代码结构,来唠一唠具体的项目结构和代码分层。
通常的项目结构
首先说在前面的是:这东西并没有一套通用的标准,不同公司或者团队的使用习惯和规范也不尽相同。
我们就以当下非常火热的Spring Boot典型项目结构为例,创建出来的项目应该总体分为三大层:
项目根目录/src/main/java
:放置项目Java源代码项目根目录/src/main/resources
:放置项目静态资源和配置文件项目根目录/src/test/java
:放置项目测试用例代码
而位于/src/main/java目录下的Java源代码的组织结构大家比较关心,这地方也只能给出一个通常典型的结构,毕竟不同项目和团队实践不一样,稍许有区别,但整体安排应该差不多。而且如果是多模块的项目的话,下面的结构应该只对应其中一个模块,其他模块的代码组织也大致差不多。
各个目录详细介绍:
|_annotation:放置项目自定义注解
|_aspect:放置切面代码
|_config:放置配置类
|_constant:放置常量、枚举等定义
|__consist:存放常量定义
|__enums:存放枚举定义
|_controller:放置控制器代码
|_filter:放置一些过滤、拦截相关的代码
|_mapper:放置数据访问层代码接口
|_model:放置数据模型代码
|__entity:放置数据库实体对象定义
|__dto:存放数据传输对象定义
|__vo:存放显示层对象定义
|_service:放置具体的业务逻辑代码(接口和实现分离)
|__intf:存放业务逻辑接口定义
|__impl:存放业务逻辑实际实现
|_utils:放置工具类和辅助代码
然后接下来/src/main/resources目录,里面主要存放静态配置文件和页面静态资源等东西:
|_mapper:存放mybatis的XML映射文件(如果是mybatis项目)
|_static:存放网页静态资源,比如下面的js/css/img
|__js:
|__css:
|__img:
|__font:
|__等等
|_template:存放网页模板,比如thymeleaf/freemarker模板等
|__header
|__sidebar
|__bottom
|__XXX.html等等
|_application.yml 基本配置文件
|_application-dev.yml 开发环境配置文件
|_application-test.yml 测试环境配置文件
|_application-prod.yml 生产环境配置文件
当然,这地方估计有一个很多人都会纠结的关于DTO/VO/DO等数据模型定义的区分。
这在《阿里巴巴Java开发手册》中倒是做了一个所谓的严格区分,那本书上是这样去定义的:
DO(Data Object)
:与数据库表结构一一对应,通过DAO层向上传输数据源对象。DTO(Data Transfer Object)
:数据传输对象,Service或Manager向外传输的对象。BO(Business Object)
:业务对象。由Service层输出的封装业务逻辑的对象。AO(Application Object)
:应用对象。在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。Query
:数据查询对象,各层接收上层的查询请求。注意超过2个参数的查询封装,禁止使用Map类来传输。VO(View Object)
:显示层对象,通常是Web向模板渲染引擎层传输的对象。
老实讲,看到这么多对象的定义,我也是很蒙的。实际项目开发时,我觉得没有必要刻意照搬去定义这么多层对象,这样后续做对象转换工作都能烦skr人。
出于简单起见,我个人觉得,只要保证业务逻辑层Service和数据库DAO层的操作对象严格划分出来,确保互相不渗透,不混用,问题应该就不大。
比如在我上面举例的这个项目的代码结构中,Service层处理的对象都定义在了dto包里,而DAO层处理的对象都放在了entity包里了。
项目结构划分总结
如果从一个用户访问一个网站的情况来看,对应着上面的项目代码结构来分析,可以贯穿整个代码分层:
我想,应该看得比较清楚了吧。
所以,以后每当我们拿到一个新的项目到手时,只要按照这个思路去看别人项目的代码,应该基本都是能理得顺的。
一些注意事项
1、Contorller层参数传递建议不要使用HashMap,建议使用数据模型定义
2、Controller层里可以做参数校验、异常抛出等操作,但建议不要放太多业务逻辑,业务逻辑尽量放到Service层代码中去做
3、Service层做实际业务逻辑,可以按照功能模块做好定义和区分,相互可以调用
4、功能模块Service之间引用时,建议不要渗透到DAO层(或者mapper层),基于Service层进行调用和复用比较合理
5、业务逻辑层Service和数据库DAO层的操作对象不要混用。Controller层的数据对象不要直接渗透到DAO层(或者mapper层);同理数据表实体对象Entity也不要直接传到Controller层进行输出或展示。
每天进步一点点,Peace!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!