Compréhension de base incontournable de la différence entre Gradle et Maven

Compréhension approfondie de la différence entre Gradle et Maven

Gradle et maven peuvent être utilisés pour créer des programmes Java, et même dans certains cas, les deux peuvent être convertis l'un à l'autre, alors quels sont les points communs et différents des deux? Comment choisissons-nous la technologie à utiliser dans le projet? Nous allons jeter un coup d'oeil.

Comparaison de Gradle et Maven

Bien que gradle et maven puissent être utilisés comme outils de construction pour les programmes java. Mais il y a encore de grandes différences entre les deux. Nous pouvons analyser à partir des aspects suivants.

Évolutivité

Google a choisi gradle comme outil de création Android sans raison. L'une des raisons les plus importantes est que gradle est suffisamment flexible. D'une part, parce que gradle utilise groovy ou kotlin comme langage de script, cela améliore considérablement la flexibilité du script, mais la raison essentielle est que l'infrastructure gradle peut supporter cette flexibilité.

Vous pouvez utiliser gradle pour créer des programmes natifs C / C ++ et même l'étendre à n'importe quel langage.

Relativement parlant, maven est moins flexible et il est plus difficile à personnaliser, mais les projets maven sont plus faciles à comprendre et à utiliser.

Donc, si votre projet n'a pas trop d'exigences de build personnalisées, il est toujours recommandé d'utiliser maven, mais si vous avez des exigences de build personnalisées, vous devriez investir dans gradle.

Comparaison des performances

Bien que les performances des machines de chacun soient relativement bonnes maintenant, il semble que l'avantage en termes de performances ne soit pas si urgent lors de la construction de projets, mais pour les grands projets, une construction peut prendre beaucoup de temps, en particulier pour la construction automatisée et l'IC En termes d'environnement, bien sûr , J'espère que cette version est aussi rapide que possible.

Gradle et Maven prennent en charge la construction de projets parallèles et la résolution des dépendances. Mais trois fonctionnalités de gradle font que gradle s'exécute un peu plus vite que maven:

  • Construction incrémentale

Afin d'améliorer l'efficacité de la construction, gradle propose le concept de construction incrémentale Afin de réaliser une construction incrémentale, gradle divise chaque tâche en trois parties, à savoir l'entrée d'entrée, la tâche elle-même et la sortie de sortie. La figure ci-dessous est une tâche compilée Java typique.

Compréhension de base incontournable de la différence entre Gradle et Maven

Prenez l'image ci-dessus à titre d'exemple, l'entrée est la version jdk cible, le code source, etc., et la sortie est le fichier de classe compilé.

Le principe de la construction incrémentale est de surveiller les changements d'entrée, et ce n'est que lorsque l'entrée est envoyée au changement que la tâche de tâche sera réexécutée, sinon gradle pense que le résultat de l'exécution précédente peut être réutilisé.

Ainsi, lors de l'écriture d'une tâche gradle, vous devez spécifier l'entrée et la sortie de la tâche.

Et il convient de noter que seuls ceux qui modifient le résultat de la sortie peuvent être appelés en entrée. Si vous définissez des variables qui ne sont absolument pas liées au résultat initial comme entrée, les modifications de ces variables entraîneront la réexécution de la tâche par gradle, ce qui entraînera perte de performance inutile.

Faites également attention aux tâches avec des résultats d'exécution incertains, par exemple, la même entrée peut obtenir des résultats de sortie différents, alors ces tâches ne pourront pas être configurées en tant que tâches de construction incrémentielles.

  • Créer un cache

Gradle peut réutiliser la sortie de la même entrée comme cache. Vous avez peut-être des questions. Ce cache et cette compilation incrémentielle ne signifient-ils pas la même chose?

Oui sur la même machine, mais le cache peut être partagé entre les machines. Si vous êtes dans un service CI, la création du cache sera très utile. Parce que la compilation du développeur peut directement extraire les résultats de la compilation du serveur CI, ce qui est très pratique.

  • Démon Gradle

Gradle lancera un démon pour interagir avec chaque tâche de build. L'avantage est qu'il n'a pas besoin d'initialiser les composants et services requis pour chaque build.

Dans le même temps, comme le démon est un processus qui s'exécute tout le temps, en plus d'éviter la surcharge de chaque démarrage de JVM, il peut également mettre en cache la structure du projet, les fichiers, les tâches et d'autres informations pour améliorer la vitesse d'exécution.

Nous pouvons exécuter gradle -status pour afficher le processus des démons en cours d'exécution.

Depuis Gradle 3.0, les démons sont activés par défaut. Vous pouvez utiliser org.gradle.daemon = false pour désactiver les démons.

Nous pouvons ressentir intuitivement la comparaison des performances de gradle et maven à travers les chiffres suivants:

  • Comparaison de l'utilisation de gradle et maven pour construire Apache Commons Lang 3:

Compréhension de base incontournable de la différence entre Gradle et Maven

  • Comparaison de l'utilisation de gradle et maven pour construire de petits projets (10 modules, 50 fichiers source et 50 fichiers de test pour chaque module):

Compréhension de base incontournable de la différence entre Gradle et Maven

  • Comparaison de l'utilisation de gradle et maven pour construire de gros projets (500 modules, 100 fichiers source et 100 fichiers de test pour chaque module):

Compréhension de base incontournable de la différence entre Gradle et Maven

Vous pouvez voir que l'amélioration des performances de gradle est très évidente.

La différence de dépendance

Gralde et maven peuvent tous deux mettre en cache les fichiers dépendants localement et tous deux prennent en charge le téléchargement parallèle de fichiers dépendants.

Dans maven, une seule dépendance peut être écrasée par le numéro de version. Gradle est plus flexible. Vous pouvez personnaliser les dépendances et les règles de remplacement. Grâce à ces règles de remplacement, gradle peut créer des projets très complexes.

Migrer de maven à gradle

Parce que maven est apparu plus tôt, pratiquement tous les projets java prennent en charge maven, mais tous les projets ne prennent pas en charge gradle. Si vous avez une idée de migrer un projet maven vers gradle, jetons un coup d'œil.

D'après notre introduction précédente, vous pouvez constater que gradle et maven sont essentiellement différents: Gradle organise les tâches via des graphiques DAG de tâches, tandis que maven exécute des tâches à travers des objectifs attachés à des phases.

Bien que la construction des deux soit très différente, grâce aux diverses conventions et règles que gradle et maven rencontrent, il n'est pas si difficile de migrer de maven à gradle.

Pour migrer de maven vers gradle, vous devez d'abord comprendre le cycle de vie de maven build. Le cycle de vie maven comprend les phases de nettoyage, de compilation, de test, de package, de vérification, d'installation et de déploiement.

Nous devons convertir la phase du cycle de vie de maven en tâches progressives du cycle de vie. Ici, vous devez utiliser le plugin de base de gradle, le plugin Java et le plugin Maven Publish.

Regardez d'abord comment introduire ces trois plugins:

plugins {
    id 'base'
    id 'java'
    id 'maven-publish'
}

Clean sera converti en tâche propre, la compilation sera convertie en tâche de classes, le test sera converti en tâche de test, le package sera converti en tâche d'assemblage, vérifiera sera converti en tâche de vérification, l'installation sera convertie en tâche Maven Publish Plugin publishToMavenLocal , le déploiement sera converti en tâche de publication dans Maven Publish Plugin.

Avec la correspondance entre ces tâches, nous pouvons essayer de convertir de maven en gradle.

Conversion automatique

En plus d'utiliser la commande gradle init pour créer une étagère gradle, nous pouvons également utiliser cette commande pour convertir un projet maven en projet gradle. La commande gradle init lira le fichier pom et le convertira en projet gradle.

Dépendance de conversion

Les dépendances gradle et maven incluent l'ID de groupe, l'ID d'artefact et le numéro de version. Les deux sont essentiellement les mêmes, mais la forme est différente. Prenons un exemple de conversion:

<dependencies>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
</dependencies>

Ce qui précède est un exemple maven, voyons comment écrire l'exemple gradle:

dependencies {
    implementation 'log4j:log4j:1.2.12'  
}

Vous pouvez voir que gradle est beaucoup plus facile à écrire que maven.

Notez que l'implémentation ici est en fait implémentée par Java Plugin.

Nous utilisons parfois l'option scope dans les dépendances maven pour indiquer l'étendue de la dépendance. Voyons comment ces étendues peuvent être converties:

  • compiler:

Il existe deux configurations pour remplacer compile dans gradle, nous pouvons utiliser l'implémentation ou l'api.

Le premier peut être utilisé dans n'importe quel gradle qui utilise Java Plugin, tandis que l'API ne peut être utilisée que dans les projets qui utilisent Java Library Plugin.

Bien sûr, il y a une différence entre les deux. Si vous créez des applications ou des applications Web, l'implémentation est recommandée. Si vous créez des bibliothèques Java, l'API est recommandée.

  • Durée:

Peut être remplacé par runtimeOnly.

  • tester:

Il existe deux types de tests dans gradle: l'un est nécessaire lors de la compilation du projet de test, puis testImplementation peut être utilisé, et l'autre est nécessaire lors de l'exécution du projet de test, puis testRuntimeOnly peut être utilisé.

  • à condition de:

Peut être remplacé par compileOnly.

  • importer:

Dans maven, l'importation est souvent utilisée dans dependencyManagement, généralement utilisé pour importer des dépendances à partir d'un fichier pom, afin d'assurer la cohérence de la version de projet dépendante dans le projet.

Dans gradle, vous pouvez utiliser platform () ou enforcedPlatform () pour importer des fichiers pom:

dependencies {
    implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE') 

    implementation 'com.google.code.gson:gson' 
    implementation 'dom4j:dom4j'
}

Par exemple, dans l'exemple ci-dessus, nous avons importé des dépendances spring-boot. Comme le numéro de version de la dépendance est déjà défini dans ce pom, nous n'avons pas besoin de spécifier le numéro de version lorsque nous introduirons gson plus tard.

La différence entre platform et enforcedPlatform est que enforcedPlatform écrasera le numéro de version importé du pom:

dependencies {
    // import a BOM. The versions used in this file will override any other version found in the graph
    implementation enforcedPlatform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE')

    // define dependencies without versions
    implementation 'com.google.code.gson:gson'
    implementation 'dom4j:dom4j'

    // this version will be overridden by the one found in the BOM
    implementation 'org.codehaus.groovy:groovy:1.8.6'
}

Convertir les référentiels

Gradle peut être compatible avec l'utilisation du référentiel maven ou lvy. Gradle n'a pas d'adresse d'entrepôt par défaut, vous devez donc en spécifier une manuellement.

Vous pouvez utiliser le référentiel maven dans gradle:

repositories {
    mavenCentral()
}

Nous pouvons également spécifier directement l'adresse de l'entrepôt maven:

repositories {
    maven {
        url "http://repo.mycompany.com/maven2"
    }
}

Si vous souhaitez utiliser l'entrepôt maven local, vous pouvez l'utiliser comme ceci:

repositories {
    mavenLocal()
}

Mais mavenLocal n'est pas recommandé, pourquoi?

mavenLocal n'est qu'un cache local de maven, et son contenu n'est pas complet. Par exemple, un module de référentiel maven local ne peut contenir que des fichiers jar, mais pas des fichiers source ou javadoc. Ensuite, nous ne pourrons pas voir le code source de ce module dans gradle, car gradle cherchera d'abord ce module dans le chemin maven local.

Et le référentiel local ne peut pas faire confiance, car le contenu à l'intérieur peut être facilement modifié sans aucun mécanisme de vérification.

Version dépendante du contrôle

S'il existe deux dépendances de versions différentes pour le même module dans le même projet, Gradle sélectionnera par défaut le package de dépendances avec la version la plus élevée après l'analyse du DAG.

Mais ce n'est pas forcément correct, nous devons donc personnaliser les fonctions qui dépendent de la version.

Le premier est l'utilisation de platform () et enforcedPlatform () mentionnés ci-dessus pour importer des fichiers de nomenclature (le type d'emballage est POM).

Si notre projet dépend d'un certain module, et que ce module dépend d'un autre module, nous l'appelons dépendance transitive. Dans ce cas, si nous voulons contrôler la version de la dépendance transitive, par exemple, mettre à niveau la version de la dépendance transitive vers une nouvelle version, nous pouvons utiliser des contraintes de dépendance:

dependencies {
    implementation 'org.apache.httpcomponents:httpclient'
    constraints {
        implementation('org.apache.httpcomponents:httpclient:4.5.3') {
            because 'previous versions have a bug impacting this application'
        }
        implementation('commons-codec:commons-codec:1.11') {
            because 'version 1.9 pulled from httpclient has bugs affecting this application'
        }
    }
}

Notez que les contraintes de dépendance ne sont valides que pour les dépendances transitives. Si le codec commun de l'exemple ci-dessus n'est pas transitif, il n'aura aucun effet.

Dans le même temps, les contraintes de dépendance nécessitent la prise en charge des métadonnées du module Gradle, ce qui signifie que cette fonctionnalité n'est prise en charge que si votre module est publié dans gradle, et qu'elle n'est pas prise en charge s'il est publié dans maven ou ivy.

Ce qui précède est la mise à niveau de version des dépendances transitives. La même chose est une dépendance transitive. Si ce projet doit également utiliser ce module dépendant de manière transitoire, mais doit utiliser une version inférieure (car le gradle par défaut utilisera la dernière version), vous devez utiliser la version rétrogradée.

dependencies {
    implementation 'org.apache.httpcomponents:httpclient:4.5.4'
    implementation('commons-codec:commons-codec') {
        version {
            strictly '1.9'
        }
    }
}

Nous pouvons spécifier une version spécifique dans l'implémentation.

Strict signifie forcer la correspondance d'un numéro de version spécifique. En plus de strictement, il y a aussi require, ce qui signifie que le numéro de version requis est supérieur ou égal au numéro de version donné. prefer, si aucun autre numéro de version n'est spécifié, utilisez prefer. Rejeter, refuser d'utiliser cette version.

En outre, vous pouvez également utiliser Java Platform Plugin pour spécifier une plate-forme spécifique afin de limiter le numéro de version.

Enfin, regardez comment exclure une dépendance:

dependencies {
    implementation('commons-beanutils:commons-beanutils:1.9.4') {
        exclude group: 'commons-collections', module: 'commons-collections'
    }
}

Projet multi-modules

Les projets multi-modules peuvent être créés dans maven:

<modules>
    <module>simple-weather</module>
    <module>simple-webapp</module>
</modules>

Nous pouvons faire la même chose dans gradle settings.gradle:

rootProject.name = 'simple-multi-module'  

include 'simple-weather', 'simple-webapp'

profil et attributs

Le profil peut être utilisé dans maven pour distinguer différents environnements. Dans gradle, nous pouvons définir différents fichiers de profil, puis les charger via des scripts:

build.gradle :

if (!hasProperty('buildProfile')) ext.buildProfile = 'default'  

apply from: "profile-${buildProfile}.gradle"  

task greeting {
    doLast {
        println message  
    }
}

profile-default.gradle :

ext.message = 'foobar'

profile-test.gradle :

ext.message = 'testing 1 2 3'

Nous pouvons l'exécuter comme ceci:

> gradle greeting
foobar

> gradle -PbuildProfile=test greeting
testing 1 2 3

Gestion des ressources

Il existe une étape process-resources dans maven, qui peut exécuter des ressources: des ressources pour copier des fichiers de ressources.

La tâche processResources du plugin Java dans Gradle peut également faire la même chose.

Par exemple, je peux effectuer la tâche de copie:

task copyReport(type: Copy) {
    from file("buildDir/reports/my-report.pdf")
    into file("buildDir/toArchive")
}

Copie plus compliquée:

task copyPdfReportsForArchiving(type: Copy) {
    from "buildDir/reports"
    include "*.pdf"
    into "buildDir/toArchive"
}

Bien sûr, il existe des applications plus complexes pour la copie. Je ne vais pas l'expliquer en détail ici.

Je suppose que tu aimes

Origine blog.csdn.net/doubututou/article/details/112919208
conseillé
Classement