工程规约 - maven 统一管理

用户头像
Man
关注
发布于: 2020 年 07 月 12 日
工程规约 - maven统一管理

一、前言

 

事情是这样的:最近条线内部在搞“避免重复造轮子”的整改活动。其中发生了一个事情,之前条线内部的A团队已经尝鲜使用了XXL-job,后面考虑到避免重复造轮子,就要求B团队新建的系统也统一使用XXL-job,然后通过执行器进行权限管理,最后才发现原来A团队使用的那个版本还没有支持权限管理。从这里,我发现到一个问题:我们的maven管理确实很混乱,依赖版本管理必须得统一管理起来。

二、一团糟



实际上,日常工作中还有其他问题的:

 

“天啊,投产包为什么会是SNAPSHOT版本?”“哪位潇洒的大侠居然引用了一个快照版的三方包?坑爹啊”“我去,生产爆了个大bug,为什么你们系统没有?噢,原来我们用的版本不一样,你真幸运。”

 

以上的问题如何解决呢?其中一个答案就是:

 

统一我们的父pom【根】,然后要求所有团队的项目直接使用这个【根】或者再基于这个【根】进行继承成自己项目的二级父pom,通过这个二级父pom进行版本管理。

 

三、如何利用父pom



1、对于某些基础包进行统一版本管理。这样的话,当子pom引用的使用就只需要groupId和artifactId即可,且当父pom的版本一改,所有子pom就会统一自动继承。

<properties>

   <java.version>1.8</java.version>

   <maven.version>3.3.7</maven.version>

   <mybatis.version>2.1.2</mybatis.version>

   <enforcer.version>1.4.1</enforcer.version>

</properties>

<dependencyManagement>

<dependencies>

   <dependency>

      <groupId>org.mybatis.spring.boot</groupId>

      <artifactId>mybatis-spring-boot-starter</artifactId>

      <version>${mybatis.version}</version>

   </dependency>

</dependencies>

 

2、在父pom加入maven-enforcer-plugin进行规则校验。

 

之前在DevOps meetup上面京东数科DevOps落地实践的线上分享中提过他们的流水线上也会用到maven-enforcer-plugin。后面做了简单的试验并结合团队的实际情况,建议我们主要用以下几个校验规则。

 

  • requireMavenVersion - enforces the Maven version.  

  • requireJavaVersion - enforces the JDK version.          

  • requireReleaseVersion - enforces that the artifact is not a snapshot.

  • banDuplicatePomDependencyVersions - enforces that the project doesn't have duplicate declared dependencies.

  • requireReleaseDeps - enforces that no snapshots are included as dependencies.

  • bannedDependencies - enforces that excluded dependencies aren't included.

 

这里以我的其中一个项目父pom作为例子,里面存着以上头4个问题,然后我们跑一下mvn validate看会报什么错误。



<?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>

    <packaging>pom</packaging>

    <modules>

        <module>validation</module>

      <module>web</module>

    </modules>

    <parent>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-parent</artifactId>

      <version>2.1.13.RELEASE</version>

      <relativePath/> <!-- lookup parent from repository -->

   </parent>

   <groupId>com.imooc</groupId>

   <artifactId>demoo</artifactId>

   <version>0.0.1-SNAPSHOT</version>

   <name>demoo</name>

   <description>Demo project for Spring Boot</description>

 

   <properties>

      <java.version>1.10</java.version>

      <maven.version>3.3.10</maven.version>

      <mybatis.version>2.1.2</mybatis.version>

      <enforcer.version>1.4.1</enforcer.version>

   </properties>

 

   <dependencies>

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-web</artifactId>

      </dependency>

      <dependency>

         <groupId>org.mybatis.spring.boot</groupId>

         <artifactId>mybatis-spring-boot-starter</artifactId>

         <version>${mybatis.version}</version>

      </dependency>

      <dependency>

         <groupId>org.mybatis.spring.boot</groupId>

         <artifactId>mybatis-spring-boot-starter</artifactId>

         <version>${mybatis.version}</version>

      </dependency>

      <dependency>

         <groupId>mysql</groupId>

         <artifactId>mysql-connector-java</artifactId>

      </dependency>

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-test</artifactId>

         <scope>test</scope>

      </dependency>

      <dependency>

         <groupId>org.projectlombok</groupId>

         <artifactId>lombok</artifactId>

         <optional>true</optional>

      </dependency>

      <!--引入JSR303校验-->

      <dependency>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-validation</artifactId>

      </dependency>

   </dependencies>

 

   <dependencyManagement>

      <dependencies>

         <dependency>

            <groupId>org.mybatis.spring.boot</groupId>

            <artifactId>mybatis-spring-boot-starter</artifactId>

            <version>${mybatis.version}</version>

         </dependency>

      </dependencies>

   </dependencyManagement>

 

   <build>

      <plugins>

         <plugin>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-maven-plugin</artifactId>

         </plugin>

         <plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-enforcer-plugin</artifactId>

            <version>${enforcer.version}</version>

            <executions>

               <execution>

                  <id>default-cli</id>

                  <goals>

                     <goal>display-info</goal>

                     <goal>enforce</goal>

                  </goals>

                  <phase>validate</phase>

                  <configuration>

                     <rules>

                        <!--Rule #1:检验maven版本-->

                        <requireMavenVersion>

                           <message>

                              <![CDATA[This application requires at least Maven with version ${maven.version}.]]>

                           </message>

                           <version>[${maven.version},)</version>

                        </requireMavenVersion>

                        <!--Rule #2:校验Java版本-->

                        <requireJavaVersion>

                           <message>

                              <![CDATA[This application requires at least JDK ${java.version}.]]>

                           </message>

                           <version>[${java.version}.0,)</version>

                        </requireJavaVersion>

                        <!--Rule #3:校验投产的版本不能是snapshot-->

                        <requireReleaseVersion>

                           <message>Snapshots version is prohibited.</message>

                        </requireReleaseVersion>

                        <!--Rule #4:校验pom文件中有没有重复的依赖(相同的GAV)-->

                        <banDuplicatePomDependencyVersions/>

                        <!--Rule #5:校验依赖冲突,如果冲突了会报错,然后在<excludes>进行排除管理即可-->

                        <bannedDependencies>

                           <!--校验传递性依赖(间接依赖)-->

                           <searchTransitive>true</searchTransitive>

                           <excludes/>

                        </bannedDependencies>

 

                        <requireProperty>

                           <property>project.version</property>

                           <message>"Project version must be specified."</message>

                           <regex>.*(\d|-SNAPSHOT)$</regex>

                           <regexMessage>"Project version must end in a number or -SNAPSHOT."</regexMessage>

                        </requireProperty>

                     </rules>

                  </configuration>

               </execution>

            </executions>

         </plugin>

      </plugins>

   </build>

 

</project>

 

当我们跑了mvn validate后,请大家对照以上pom文件看以下截图,你可以发现上面的头4个错误基本可以在构建环节直接识别,这样的话就可以在技术上有效的约束工作规范,这样是不是更好的体现“约定优于配置”呢?

 

当然,具体maven-enforcer-plugin还有更多的校验规则,或者你也可以基于它的规范开发你特有的校验规则。具体可以参考阿帕奇http://maven.apache.org/enforcer/maven-enforcer-plugin/index.html



四、后话



实际上这个就是我自己构想中的DevOps持续构建流水线上的关于质量关卡的其中一个小环节。诚然,在工程规约这个大命题下面,实际我们还有更多的事情需要做,后面再慢慢摸索,定期更新完善这个DevOps流水线。



发布于: 2020 年 07 月 12 日 阅读数: 93
用户头像

Man

关注

尘世间一名迷途小码农 2020.06.24 加入

1、致力于成为一名DevOps Geek,热衷于用技术方式去解决问题,厌恶低效,热衷自动化和智能化,释放人的创造性。 2、CSDN博客:https://blog.csdn.net/justyman

评论

发布
暂无评论
工程规约 - maven统一管理