With Gradle, will you still choose Maven?

Many people are still torn between using Maven or Gradle. If you have followed the article published in InfoQ by Mr. Xu Xiaobin, the author of "Maven Authoritative Guide": "Maven in Action (6) - Gradle, the future of build tools? , then there must be the same feeling: Gradle is too flexible and may be uncontrollable. The original words in the article are:

"Another problem with Gradle is that it is too flexible. Although it supports convention over configuration, you can also see from this article how easy it is to break convention. Everyone likes freedom and customization, and feels that their needs are How special, but in fact, from the popularity of Maven, almost 95% of the time you don't need to scale it yourself, if you do, it will only make the build difficult to understand. From this perspective, freedom is Double-edged sword, Gradle gives you enough freedom that convention over configuration is just an option, which at first looks tempting, but could also make it a repeat of Ant's mistakes."

First look at the build.gradle we originally used to build the Spring Cloud project with Gradle:

buildscript {
    ext {
        springCloudVersion = 'Edgware.SR3'
        springBootVersion = '1.5.9.RELEASE'
        REPOSITORY_HOME = "http://maven.aliyun.com"
    }
    repositories {
        maven { url "${REPOSITORY_HOME}/nexus/content/groups/public" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
apply plugin: 'maven'
apply plugin: 'java'
apply plugin: 'org.springframework.boot'

if (JavaVersion.current().isJava8Compatible()) {
    allprojects {
        tasks.withType(Javadoc) {
            options.encoding = 'UTF-8'
            options.addStringOption('Xdoclint:none', '-quiet') // 关闭JDK1.8的doclint特性
        }
    }
}
// 导入Spring Cloud 依赖
dependencyManagement {
  imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
  }
}

dependencyManagement {
  resolutionStrategy {
    // 检查远程依赖是否存在更新
    cacheChangingModulesFor 0, 'seconds'
    cacheChangingModulesFor 0, 'seconds' // 修改本地缓存策略
  }
}

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

bootRepackage {
  // 默认只打普通jar包
  enabled = false
}

// 打包源代码,为了方便查看源码及调试,把源码也上传到nexus仓库中
task sourcesJar(type: Jar) {
  classifier = 'sources'
  from sourceSets.main.allSource
}

// 打javadoc包,为了方便查看注释,需要把javadoc也上传到nexus仓库中
task javadocJar(type: Jar, dependsOn: javadoc) {
  classifier = 'javadoc'
  from javadoc.destinationDir
}

artifacts {
  archives jar
  archives sourcesJar
  archives javadocJar
}

uploadArchives {
    repositories {
        mavenDeployer {
            snapshotRepository(url: "${REPOSITORY_HOME}/nexus/content/repositories/snapshots/") {
                authentication(userName: 'xxx', password: 'xxx')
            }
            repository(url: "${REPOSITORY_HOME}/nexus/content/repositories/releases/") {
                authentication(userName: 'xxx', password: 'xxx')
            }
        }
    }
}

version = '0.0.1' // 设置版本
group = 'com.suixingpay.demo' // 设置group id
description = 'demo' // 设置描述

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-web')
    compileOnly('org.springframework.boot:spring-boot-configuration-processor')
    compileOnly('org.projectlombok:lombok')
    testCompile('org.projectlombok:lombok')
    testCompile "org.springframework.boot:spring-boot-starter-test"
}

From the above code we can see the following problems:

  1. Although the dependencies part of the code is much less than maven, but overall, the code is not concise;
  2. There are risks brought by hard coding. For example, when you want to modify the address of the Maven repository, or the user name and password, you need to notify everyone to make the change;
  3. In addition to the buildscript code block, the gradle code does not have the same structural writing requirements as the xml in maven, which may cause everyone to write differently;
  4. It is difficult to distinguish the configuration of each plug-in, which is very painful for people who are not familiar with plug-ins, and very inconvenient to maintain;
  5. When there are many projects, there will be a lot of repetitive code, which increases a lot of repetitive development and maintenance costs; for example, there was no requirement to upload the source code and javadoc to the maven warehouse before, but later for various reasons, this requirement was added, then You need to notify everyone to modify all the code again;

Our original idea was to maintain the above code using different gradle files according to different plugins, and then put them in the GRADLE_HOME/init.d/ directory, but it is still difficult to update.

Supplementary description of the loading order of init.gradle. Gradle will detect some directories in turn, and load the files in these directories according to their priorities. If multiple files are found in a directory, they will be loaded in alphabetical order. The loading priority is as follows:

  1. Specify the path at the start of the build via the -I or --init-script parameter, e.g.

     gradle --init-script init.gradle clean
    
     gradle --I init.gradle assembleDebug
    
  2. Load USER_HOME/.gradle/init.gradle file

  3. Load the files ending with .gradle in the USER_HOME/.gradle/init.d/ directory

  4. Load the file ending with .gradle in the GRADLE_HOME/init.d/ directory

Later research found that gradle can load external gradle files through the apply from command, and even load files in remote http servers. We are so excited about this discovery, it can help us solve all the above problems.

First split the content of build.gradle above into multiple files:

  1. Put the maven-related code into the maven.gradle file;
  2. Because java, spring boot and Spring Cloud are the plugins we use the most, we put their related code in the same file: spring-cloud.gradle , but the versions of Spring boot and Spring Cloud will vary depending on the project. Different versions are used, so they need to be extracted separately, such as: spring-cloud-dalston-sr4.gradle , spring-cloud-edgware.gradle

Then put the split files above into the git repository and modify the build.gradle file:

buildscript { // buildscript 不能抽取出来,只能重复写。
  ext{
    sxGradleHome = "https://gitee.com/sxfad/gradle-scripts/raw/master/"
  }
  apply from: sxGradleHome + 'maven.gradle'
  apply from: sxGradleHome + 'spring-cloud-edgware.gradle' // 导入使用Spring Cloud及相应的Spring Boot版本号
  repositories {
    maven { url REPOSITORY_URL }
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
}

// 更详细的说明请参考 https://gitee.com/sxfad/gradle-scripts/
apply from: sxGradleHome + 'maven.gradle'
apply from: sxGradleHome + 'spring-cloud.gradle'

version = '0.0.1' // 设置版本
group = 'com.suixingpay.demo' // 设置group id
description = 'demo' // 设置描述

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-web')
    compileOnly('org.springframework.boot:spring-boot-configuration-processor')
    compileOnly('org.projectlombok:lombok')
    testCompile('org.projectlombok:lombok')
    testCompile "org.springframework.boot:spring-boot-starter-test"
}

After the above method is processed, it brings us the following benefits:

  1. The modified build.gradle becomes extremely concise, you only need to care about its basic information and dependencies;
  2. For the company's internal use, the use of gradle is more standardized and standard, and the use becomes easier;
  3. Because the core gradle file is placed on the remote server, it is very convenient to update and maintain; and after using git management, it also has a "version management" function (convenient to view the file modification history, rollback, etc.);

After seeing this, you will no longer struggle with choosing Maven or Gradle, and even fall in love with Gradle.

For more detailed instructions, please refer to https://gitee.com/sxfad/gradle-scripts/

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324139553&siteId=291194637