背景
互联网发展到现在,从刚开始的单体单机架构到现在的分布式微服务架构,虽然带来了不胜枚举的好处和便利,但是也让新应用的或者新业务板块的搭建增加了游戏难度,举个具体的场景,应用经过应用模块细分和代码分层后大致变成了这个样子:
整个应用里边有以下模块:
那么按照既定应用模块化和代码分层规范,如果要新搭建一个应用,我有以下n多工作要纯手工完成:
- 创建1个父模块与9个子模块
- 梳理模块之间的继承和依赖关系&每个模块引入基础依赖
- 手动引入通用的中间件依赖和spring相关依赖
- 配置数据库连接配置、配置中心、启动类&以及项目启动配置、日志配置等
- 手动定义工具类
这些复杂繁琐的工作,就算是一个经验丰富的工程师,从应用搭建到项目初步跑起来至少也要一天的时间,在互联内网的今天,我们极度推崇提效降本,那么把这些复杂的工作抽象成模板是势在必行的,工程师只需要几行命令或者极少的手动操作就能生成一个拆箱即用的项目,而把更多的精力和时间花在关注领域业务和服务。
那么本篇文章将从零开始,搭建一个基于领域模型的多模块项目骨架,并且能够根据模板搭建新应用且经过简单修改配置就能运行,大致目录和步骤如下:
- 新建骨架项目
- 骨架项目生成项目骨架
- 将骨架安装到本地并根据骨架生成新应用
- 将骨架发布到私服并根据骨架生成新应用
- 将骨架发布到maven中央仓库
一、新建骨架项目
1:基于maven-archetype-quickstart生成一个简单maven项目
groupId:com.typhoon.skeleton
artifactId:skeleton
version:1.0-SNAPSHOT
- 删除skeleton项目下除pom.xml的所有文件,并修改打包方式为pom
- 继承spring-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/>
</parent>
- 添加每个模块都会用到的lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
</dependency>
- 声明一些通用依赖版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.5.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- jdbcTemplate -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<!-- mysql connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!-- logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2:基于父模块新建子模块
各个模块之间的分层和依赖关系如上图,每个模块的定位和作用如下:
- web:接收http请求
- client:暴露rpc接口
- test:http和rpc端服务测试用例
- manager:web端服务实现
- provider:rpc接口服务实现
- service:web端和client端通用服务下沉与实现
- dao:领域内数据交互实现
- proxy:外部服务调用代理
- common:通用常量和工具类定义
- launcher:服务启动门面
具体每个模块代码实现不做赘述,有兴趣可以关注我的git项目。
二、生成项目骨架
1:在父模块pom中添加archetype插件&开发者信息
archetype
代码语言:javascript复制<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<propertyFile>archetype.properties</propertyFile>
</configuration>
</plugin>
developer
代码语言:javascript复制<developers>
<developer>
<name>Typhoon</name>
<email>ScorpioAeolus@gmail.com</email>
<organization>Typhoon is comming!</organization>
<organizationUrl>https://scorpioaeolus.oschina.io/typhoon/</organizationUrl>
</developer>
</developers>
2:在父模块根目录下添加archetype.properties
代码语言:javascript复制archetype.groupId=com.typhoon.skeleton
archetype.artifactId=skeleton
archetype.version=1.0-SNAPSHOT
archetype.filteredExtensions=java
archetype.languages=groovy
## generate for archetype-metadata.xml
excludePatterns=archetype.properties,*.iml,.idea/,.idea/libraries,logs/,build.sh
## generate .gitignore file
gitignore=.gitignore
3:在项目根目录下执行命令生成骨架项目
代码语言:javascript复制mvn archetype:create-from-project -Darchetype.properties=./archetype.properties
在项目根目录下生成了target,目录结构如下:
三、将archetype安装到本地&根据archetype生成应用
1:进入骨架项目目录并安装到本地
代码语言:javascript复制cd target/generated-sources/archetype/
mvn clean install
在本地maven仓库中会生成如下目录和文件:
2:使用自定义archetype生成应用
- 使用mvn命令生成
mvn archetype:generate
-DgroupId=com.shuya.reverse
-DartifactId=reverse-center
-Dpackage=com.shuya.reverse.center
-DarchetypeGroupId=com.typhoon.skeleton
-DarchetypeArtifactId=skeleton
-DarchetypeVersion=1.0-SNAPSHOT
-DinteractiveMode=false
- 基于IntelliJ IDEA生成
新建maven项目的时候,添加自定义archetype,然后指定package:
新生成的项目目录结构如下:
使用maven命令编译项目:
mvn -U clean compile
编译通过:
调整dao层数据库配置和launcher的启动类扫描包路径后启动应用
启动应用:
启动成功后直接尝试发送http请求:
curl http://localhost:8080/user/1
正常拿到结果:
四、将archetype发布到私服&根据archetype生成应用
1:进入骨架项目目录并depoly到私服
代码语言:javascript复制cd target/generated-sources/archetype/
mvn clean deploy
在nexus仓库中会生成如下目录和文件:
2:使用自定义archetype生成应用
首先要删掉本地仓库的archetype,因为项目项目寻找依赖的时候优先在本地仓库寻找,如果找到就直接返回,找不到才去远程仓库下载,为了不让本地的archetype影响nexus中archetype使用,先删除本地仓库自定义archetype:
接下来使用mvn命令和基于IDEA创建应用以及应用编译和初步运行和上一节中相同,这里不做重复描述。
五、将骨架发布到maven中央仓库
以上步骤完成后,我们的自定义骨架只能在本地或者团队内用,如果要想像使用其他maven项目骨架一样,全世界都可以使用,那么久需要将我们的项目骨架发布到中央仓库,而发布到中央仓库需要以下几个步骤:
- 注册Sonatype账号
https://issues.sonatype.org/secure/Signup!default.jspa
- 创建一个 Issue&等待审核通过
- 注册域名
- 发布自定义骨架
相当繁琐并且需要等待官方审核,这里不展开讲述,客参考:https://my.oschina.net/huangyong/blog/226738
六、总结
经过上述长篇论述,我们把引用模块化细分和代码分层和自定义多模块maven项目模板搭建过程详细描述了一番,重点讲解的还是自定义项目骨架的生成过程以及使用,并且简单对生成项目的改造,就能初步运行,极大地节省了新应用搭建和配置的人力成本,让开发人员更多的关注业务实现和编码,而不是花在千篇一律的项目基础结构搭建上。另外可以基于该骨架项目进行改造升级和定制化,对于不同的团队或者平台,可能使用的基础架构和配置不尽相同,改造后可以形成团队或者平台个性化自定义项目骨架。
参考:
http://maven.apache.org/archetype/maven-archetype-plugin/examples/create-with-property-file.html
https://maven.apache.org/archetype/maven-archetype-plugin/specification/archetype-metadata.html