在单机架构下,我们只需要将我们的依赖在pom中引入。但是过渡到微服务架构后,会涉及到多模块引用相同的依赖,多模版之间依赖的版本太过分散难以管理的问题。
这就需要我们利用maven中依赖传递的特性,结合dependencyManagement标签来做好依赖的版本管理。下面我们就通过具体的案例来向大家演示如何在微服务架构中做好pom的管理规范。
<pluginRepositories>
<pluginRepository>
<id>nexusid>
<name>xxx-mavenname>
<url>http://xxx:8083/nexus/content/groups/public/url>
pluginRepository>
pluginRepositories>
我们先来看我们的案例:
有一个微服务架构,包含商品模块product,订单模块order,网关模块gateway,还有一个公用模块common
其中商品模块、订单模块都需要引入nacos、mybatis-plus、swagger、mysql、lombok等依赖
订单模块中除了上述所说的依赖,还需要引入xxl等依赖
网关模块需要引入nacos、discovery、gateway、jwt、lombok依赖
以下配置在父项目pom.xml中操作
首先我们先将所需要的依赖的版本号定义为属性,在父项目pom.xml中管理
<properties>
<java.version>1.8java.version>
<maven.version>3.8.1maven.version>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<spring-boot.version>2.1.1.RELEASEspring-boot.version>
<spring-cloud-alibaba.version>2.1.1.RELEASEspring-cloud-alibaba.version>
<lombok.version>1.18.22lombok.version>
<swagger.version>2.9.2swagger.version>
<mybatis-plus.version>3.3.2mybatis-plus.version>
<xxl-job-core.version>2.2.0xxl-job-core.version>
properties>
其次我们在dependencyManagement标签中将所有的依赖做好版本声明
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring-boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>${spring-cloud-alibaba.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
<dependency>
<groupId>com.alibaba.nacosgroupId>
<artifactId>nacos-clientartifactId>
<version>${seata-version}version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>${swagger.version}version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>${swagger.version}version>
dependency>
<dependency>
<groupId>com.xuxueligroupId>
<artifactId>xxl-job-coreartifactId>
<version>${xxl-job-core.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${mybatis-plus.version}version>
dependency>
dependencies>
dependencyManagement>
这里咱们要注意的是,spring-boot-dependencies和spring-cloud-alibaba-dependencies等依赖实际上并不是jar包,我们点击进去就可以知道,这是一个聚合项目,里面声明了常用的依赖的版本
我们通过引用这个线程的聚合项目,节省了大量常用依赖的版本管理
其次我们再在父项目中声明一下项目的jdk、maven版本以及编码格式。如果项目中有通用的maven插件配置,也可以在这里声明
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>${maven.version}version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
<encoding>UTF-8encoding>
configuration>
plugin>
plugins>
build>
以下配置在common模块的pom.xml中操作
基于这样的一个案例,我们首先知道的是商品模块和订单模块中都有很多相同的依赖,那么我们把这些相同的依赖添加到公用模块中,如果没有公用模块,可以创建一个,专用于存储公用的实体类、工具类、公共依赖登
首先我们需要声明父项目,以此使用父项目中声明的依赖版本
<parent>
<artifactId>smart-ufenartifactId>
<groupId>cn.smartlink.ufengroupId>
<version>1.1.0-SNAPSHOTversion>
parent>
其次将公用的依赖声明出来,这里会发现我们这里的依赖是没有声明版本的,这是因为我们已经在父项目中将版本声明好了。这也就是我们要做版本管理的意义所在
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>com.alibaba.nacosgroupId>
<artifactId>nacos-clientartifactId>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
dependencies>
1、然后在商品模块和订单模块引入common模块
<parent>
<artifactId>smart-ufenartifactId>
<groupId>cn.smartlink.ufengroupId>
<version>${parent.version}version>
<relativePath>../../pom.xmlrelativePath>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>smart-ufen-admin-coreartifactId>
<dependencies>
<dependency>
<groupId>cn.smartlink.ufengroupId>
<artifactId>smart-ufen-commonartifactId>
<version>1.1.0-SNAPSHOTversion>
dependency>
dependencies>
后续就可以只在common中添加或者修改依赖,就能实现各个模块的公用依赖统一管理
需要注意的是:子项目中一定要用parent标签声明好父项目
2、因为订单模块中还多了其他几个依赖,所以我们除了common外还要在订单的pom中额外引入其他依赖
<parent>
<artifactId>smart-ufenartifactId>
<groupId>cn.smartlink.ufengroupId>
<version>1.1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>order-server-feignartifactId>
<version>${parent.version}version>
<name>${project.artifactId}name>
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>dynamic-datasource-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>io.github.openfeigngroupId>
<artifactId>feign-httpclientartifactId>
dependency>
<dependency>
<groupId>com.examplegroupId>
<artifactId>product-server-feignartifactId>
<version>${parent.version}version>
dependency>
dependencies>
3、common中的公用依赖大部分网关模块都不需要,所以我们干脆就网关模块的依赖单独引入
<parent>
<artifactId>smart-ufenartifactId>
<groupId>cn.smartlink.ufengroupId>
<version>1.1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>gatewayartifactId>
<version>${project.parent.version}version>
<name>${project.artifactId}name>
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>io.jsonwebtokengroupId>
<artifactId>jjwtartifactId>
dependency>
dependencies>
所谓聚合项目,就是单独的一个空maven项目,只有pom文件,专门用于依赖的版本声明,其他的项目通过引入该聚合项目来实现依赖版本管理
这个比在父项目中进行版本管理更加凸显模块的专业化
1、创建一个空maven项目,只保留pom.xml文件。将该项目的打包方式声明为pom
<packaging>pompackaging>
2、然后将上述的父项目中的dependencyManagement标签中的依赖管理添加到聚合项目的pom文件中
3、在商品服务、订单服务、网关服务、common服务中引入该聚合项目,从而实现版本的统一管理
<sourceDirectory />
<testSourceDirectory />
<outputDirectory />
<testOutputDirectory />
<scriptSourceDirectory />
路径管理定义了各种源码和编译结果的输出路径。如果遵循maven默认的路径约定,这里的几个元素是不需要配置的。
<resources>
<resource>
<targetPath />
<filtering />
<directory />
<includes />
<excludes />
resource>
resources>
<testResources>
<testResource>
<targetPath />
<filtering />
<directory />
<includes />
<excludes />
testResource>
testResources>
这里的元素主要是对应用程序resource资源和单元测试部分resource资源的管理,分别通过resource标签和testResource标签管理两种资源。一般需额外引用maven中没有的第三方jar时使用。
<pluginManagement>
<plugins>
<plugin>
<groupId />
<artifactId />
<version />
<extensions />
<executions>
<execution>
<id />
<phase />
<goals />
<inherited />
<configuration />
execution>
executions>
<dependencies>
......
dependencies>
<inherited />
<configuration />
plugin>
plugins>
pluginManagement>
<plugins>
......
plugins>
插件管理相关的元素有两个,包括pluginManagement和plugins。pluginManagement中有子元素plugins,它和project下的直接子元素plugins的区别是,pluginManagement主要是用来声明子项目可以引用的默认插件信息,这些插件如果只写在pluginManagement中是不会被引入的。project下的直接子元素plugins中定义的才是这个项目中真正需要被引入的插件。
父 pom
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
<encoding>UTF-8encoding>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-checkstyle-pluginartifactId>
<version>3.1.1version>
<executions>
<execution>
<phase>compilephase>
<goals>
<goal>checkstylegoal>
goals>
execution>
executions>
<configuration>
<configLocation>META-INF/configs/quality/checkstyle/checkstyle.xmlconfigLocation>
configuration>
<dependencies>
<dependency>
<groupId>com.smartlink.middleofficegroupId>
<artifactId>middleoffice-qualityartifactId>
<version>2.0.0version>
dependency>
dependencies>
plugin>
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>findbugs-maven-pluginartifactId>
<version>3.0.5version>
<configuration>
<excludeFilterFile>META-INF/configs/quality/findbugs/excludeFilter.xmlexcludeFilterFile>
<findbugsXmlOutputDirectory>
${project.build.directory}/findbugs
findbugsXmlOutputDirectory>
configuration>
<executions>
<execution>
<phase>compilephase>
<goals>
<goal>findbugsgoal>
goals>
execution>
executions>
<dependencies>
<dependency>
<groupId>com.smartlink.middleofficegroupId>
<artifactId>middleoffice-qualityartifactId>
<version>2.0.0version>
dependency>
dependencies>
plugin>
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>xml-maven-pluginartifactId>
<version>1.0version>
<executions>
<execution>
<phase>compilephase>
<goals>
<goal>transformgoal>
goals>
execution>
executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/findbugsdir>
<outputDir>${project.build.directory}/siteoutputDir>
<stylesheet>default.xslstylesheet>
<fileMappers>
<fileMapper
implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>.htmltargetExtension>
fileMapper>
fileMappers>
transformationSet>
transformationSets>
configuration>
<dependencies>
<dependency>
<groupId>com.google.code.findbugsgroupId>
<artifactId>findbugsartifactId>
<version>3.0.1version>
dependency>
dependencies>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-pmd-pluginartifactId>
<version>3.11.0version>
<executions>
<execution>
<phase>compilephase>
<goals>
<goal>pmdgoal>
goals>
execution>
executions>
<configuration>
<printFailingErrors>trueprintFailingErrors>
<targetDirectory>${project.build.directory}/pmdtargetDirectory>
<rulesets>
<ruleset>META-INF/configs/quality/pmd/ali-comment.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-concurrent.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-constant.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-exception.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-flowcontrol.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-orm.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-other.xmlruleset>
<ruleset>META-INF/configs/quality/pmd/ali-set.xmlruleset>
rulesets>
configuration>
<dependencies>
<dependency>
<groupId>com.alibaba.p3cgroupId>
<artifactId>p3c-pmdartifactId>
<version>2.0.1version>
dependency>
<dependency>
<groupId>com.smartlink.middleofficegroupId>
<artifactId>middleoffice-qualityartifactId>
<version>2.0.0version>
dependency>
dependencies>
plugin>
plugins>
build>
子 pom
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
<configuration>
<classifier>bootclassifier>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-jar-pluginartifactId>
<configuration>
<excludes>
<exclude>**/application*.propertiesexclude>
<exclude>**/bootstrap*.ymlexclude>
<exclude>**/bootstrap*.yamlexclude>
<exclude>**/logback*.xmlexclude>
excludes>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<version>2.12.4version>
<configuration>
<skipTests>trueskipTests>
configuration>
plugin>
plugins>
build>