前言
關於微服務的公共依賴模塊的抽取、統一版本管理、統一私服配置等,嘗試了多種方案,整理優化了多次,分享一下。
期望達到的效果:
1、統一的三方庫版本管理
2、統一的私服配置(上傳、下載、下載插件)
3、springcloud springalibaba springboot 版本依賴管理統一配置
正文
單獨建一個common的maven工程,內部生成一個core module。
核心就兩塊,一塊是最外層的 common-parent(pom artifacId的名字),一塊是內層的common
關係圖
common工程
common的功能:
- 公共類、公共工具類
- 公共三方依賴
- 注意:common的packaging是jar
common-parent的功能:
- 版本的統一管理
- springboot springcloud springalibaba 版本管理
- 私服的配置
- 注意:common-parent的packaging是pom
外層的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
</parent>
<groupId>com.xiaoxi</groupId>
<artifactId>common-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<description>common-parent</description>
<packaging>pom</packaging>
<modules><module>core</module></modules>
<!-- 統一版本管理 -->
<properties>
<mybatis-plus.version>3.4.0</mybatis-plus.version>
<dynamic-datasource.version>3.3.2</dynamic-datasource.version>
<p6sy.version>3.8.7</p6sy.version>
<mysql-connector.version>8.0.13</mysql-connector.version>
<knife4j.version>2.0.7</knife4j.version>
<lombok.version>1.18.12</lombok.version>
<hutool.version>5.3.8</hutool.version>
<java.version>1.8</java.version>
<seata.version>1.4.0</seata.version>
<nacos.version>2.2.1.RELEASE</nacos.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>
<!-- springcloud springAlibaba 依賴版本管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<type>pom</type>
<version>${spring-cloud.version}</version>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>${seata.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!--拉取倉庫-->
<repositories>
<repository>
<id>maven_xiaoxi</id>
<url>http://192.168.148.237:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<!--插件拉取倉庫-->
<pluginRepositories>
<pluginRepository>
<id>maven_xiaoxi</id>
<url>http://192.168.148.237:8081/repository/maven-public/</url>
<releases>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<!--發佈倉庫-->
<distributionManagement>
<repository>
<id>maven_xiaoxi</id>
<url>http://192.168.148.237:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven_xiaoxi</id>
<url>http://192.168.148.237:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
內層core的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common-parent</artifactId>
<groupId>com.xiaoxi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<artifactId>common</artifactId>
<!-- 公共依賴 -->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-datasource.version}</version>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>${p6sy.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<artifactId>httpclient</artifactId>
<groupId>org.apache.httpcomponents</groupId>
</exclusion>
</exclusions>
<version>${nacos.version}</version>
</dependency>
<!-- seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.2.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>${seata.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>
發佈
每次發佈,最好先clean,然後在最外層maven deploy即可。(因爲他們是父子級關係)
微服務
xxxx-interface
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xiaoxi</groupId>
<artifactId>common-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>test1-interface</artifactId>
<dependencies>
<dependency>
<groupId>com.xiaoxi</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven_xiaoxi</id>
<url>http://192.168.148.237:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
可以看到,這裏interface,是繼承了common-parent,因爲它是在私服上面的,所以無論如何你也需要配置一個私服的拉取倉庫。但是好處是,你繼承了common-parent,等於裏面的 下載、插件下載、發佈的配置都有了,就不必再配置發佈了。
xxxx-service
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiaoxi</groupId>
<artifactId>common-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.example</groupId>
<artifactId>test1-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test1-service</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>test1-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!-- 通過maven的profile來 動態修改spring的profile 達到多套配置切換使用的效果 -->
<profiles>
<profile>
<!-- 本地環境 -->
<id>local</id>
<properties>
<profiles.active>local</profiles.active>
<skipDocker>true</skipDocker>
<dockerHost></dockerHost>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 開發環境 -->
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
<skipDocker>true</skipDocker>
<dockerHost>http://192.168.148.236:2375</dockerHost>
</properties>
</profile>
<profile>
<!-- 測試環境 -->
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
<skipDocker>false</skipDocker>
<dockerHost>http://192.168.148.235:2375</dockerHost>
</properties>
</profile>
<profile>
<!-- 生產環境 -->
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
<skipDocker>false</skipDocker>
<dockerHost>http://xxxx:2375</dockerHost>
</properties>
</profile>
</profiles>
<!-- maven插件發佈到docker中 -->
<build>
<!-- 引用我們的項目名字 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>maven_xiaoxi</id>
<url>http://192.168.148.237:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
service,現在就清爽很多了。只需要繼承common-parent,加上私服拉取,就可以節省很多配置了。依賴的話,只需要微服務模塊間的 和 自己的 interface的依賴即可。
依賴關係爲:
xxxx-service -> xxxx-interface -> common
繼承關係爲
xxx-interface -> common-parent
xxx-service -> common-parent
關於service想要自定義版本的實現
在整理優化的過程中發現一個問題,就是:
我們公共依賴裏面配置的seata版本是1.4.0,而最終在service裏面的版本是1.1.0。
這是爲什麼呢?這就跟maven的依賴加載順序有關係了。
這裏也簡述一下:
我們大致把依賴分爲這幾個級別:
- 本級
<dependencies> 自身的工程的直接依賴
- 上級
<parent> 自身工程的parent繼承
- 下級
依賴的庫的依賴 自身工程依賴的三方庫 的 依賴
- 版本管理
<dependencyManagement> 自身工程的版本管理
優先級順序爲:
本級 > 本級版本管理 > 上級 > 上級版本管理 > 下級 (無下級版本管理)
而對照我們的公共依賴庫的話:
我們parent繼承的common-parent的版本優先級是高於 依賴的第三方common的依賴的版本的
也就是說,common裏面是1.4.0,而parent裏面是1.1.0(springalibaba),此時最終就會以1.1.0爲最優先。
下面是圖
那麼這種情況怎麼辦呢?
我們知道maven的依賴如果是有多個相同的,那麼後面的會覆蓋前面的配置。
在我們common-parent的dependencyManagement裏面已經定義了 springalibaba,那麼我們就可以在下面重新指定一下 seata的版本爲1.4.0,這樣對於common-parent而言最終其實seata版本就是1.4.0了。
對照加載順序就是:
- 原來:
本級(無) > 本級版本管理 (無) > 上級(無) > 上級版本管理 (common-parent 1.1.0)> 下級 (common 1.4.0) (無下級版本管理)
- 現在:
本級(無) > 本級版本管理 (無) > 上級(無) > 上級版本管理 (common-parent 1.4.0)> 下級 (common 1.4.0)
關於作者
作者是一個熱愛學習、開源、分享,傳播正能量,喜歡打籃球、頭髮還很多的程序員-。-
熱烈歡迎大家關注、點贊、評論交流!
簡書:https://www.jianshu.com/u/d234d1569eed
github:https://github.com/fly7632785