Into the world of JavaWeb technology 12: From manual compilation and packaging to project build tool Maven

Into the world of JavaWeb technology 12: From manual compilation and packaging to project build tool Maven

This series of articles will be organized into my "Java Interview Guide" repository on GitHub. For more exciting content, please check in my repository

https://github.com/h2pl/Java-Tutorial

If you like it, please click on Star

The article was first published on my personal blog:

www.how2playlife.com

This article is one of the "Into the World of JavaWeb Technology" published by the WeChat public account [Java Technology Jianghu]. Part of the content of this article comes from the Internet. In order to make the subject of this article clear and thorough, it also integrates many technical blogs that I think are good. Some of the better blog posts are cited. If there is any infringement, please contact the author.

This series of blog posts will tell you how to learn the basics of JavaWeb step by step from entry to advanced, from servlet to framework, from ssm to SpringBoot, and get started with actual combat, and then learn about the technologies and components that are often used in JavaWeb projects. Including log components, Maven, Junit, etc., so that you can have a more complete understanding of the entire JavaWeb technology system and form your own knowledge framework.

If you have any suggestions or questions about this series of articles, you can also follow the public account [Java Technology Jianghu] to contact the author, and you are welcome to participate in the creation and revision of this series of blog posts.

At the end of the article, 8000G of learning materials for Java architects will be presented. Friends in need can learn about the way to receive them at the end of the article. The materials include free learning materials such as Java basics, advanced, projects, and architects, as well as popular technologies such as databases, distributed, and microservices. The video is rich in content, taking into account principles and practices, and will also give away the author s original Java study guide, Java programmer interview guide and other dry goods resources)

Introduction to maven

1.1 What is Maven

Maven is a project management and comprehensive tool. Maven provides developers to build a complete life cycle framework. The developer team can automatically complete the construction of the basic tools of the project. Maven uses a standard directory structure and a default build life cycle.

In a multi-developer team environment, Maven can be set to complete the configuration work in a very short time according to the standard. Since most of the project settings are simple and reusable, Maven makes the developer's work easier, while creating reports, checking, building, and testing automation settings.

Students who have used GitHub should feel familiar here. Yes, Maven and git have similar functions, both for the convenience of project creation and management.

In a nutshell, Maven simplifies and standardizes the project construction process. Handles compilation, distribution, documentation, teamwork and other tasks seamlessly. Maven increases reusability and is responsible for establishing related tasks.

1.2 History of Maven

Maven was originally designed to simplify the construction of the Jakarta Turbine project. In several projects, each project contains different Ant build files. JAR checked to CVS. The Apache organization develops Maven to create multiple projects, publish project information, project deployment, and JAR files provide teamwork and help in several projects.

Maven has experienced the development of Maven-> Maven2 -> Maven3.

1.3 Why use Maven

Before Maven, we often used Ant to build Java projects. Then Ant is only a build tool. It does not manage the project dependencies and the project itself, and Ant as a build tool fails to eliminate the repetitiveness of software builds. , Because different projects need to write corresponding Ant tasks.

As a latecomer, Maven inherited Ant's project construction function, and provided dependencies and project management functions. Therefore, it is a project management and comprehensive tool. Its core dependency management, project information management, and central warehouse are more than configuration. The core functions of Maven make Maven the standard choice for current Java project construction and management tools.

There are many reasons to learn Maven:

Mainstream IDEs (Eclipse, IDEA, Netbean) have built-in Maven

SpringFramework no longer provides jar downloading, and download dependencies directly through Maven.

On github, almost all popular Java projects in the open source community are built and managed through Maven.

Getting started with Maven

Maven concept

As a build tool, Maven can not only help us automate the build, but also abstract the build process and provide the realization of build tasks; it is cross-platform and provides a consistent operation interface to the outside, all of which is enough to make it an excellent and popular build tool.

Maven is not only a build tool, but also a dependency management tool and project management tool. It provides a central warehouse and can help me download components automatically.

maven installation

One: Because I am a window system, I only introduce how to install under windows. Before installing Maven, please make sure you have installed JDK. ![image.png ](http://upload-images.jianshu.io/upload_images/5811881-5a7737962f83f677.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

Two: Then go to the download interface of Maven official website to download the desired version and unzip it to the directory you want ! [image.png ](http://upload-images.jianshu.io/upload_images/5811881-16d9fd82c7f938ae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

![image.png ](http://upload-images.jianshu.io/upload_images/5811881-7482108a7ff71031.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

Three: Finally, set the environment variables and configure the Maven installation to the operating system environment, mainly to configure M2_HOME and PATH, as shown in the figure ! [image.png ](http://upload-images.jianshu.io/upload_images/5811881-ffdf167e64415703.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

After everything is done, verify it, open doc and enter mvn -v. How to get the following information indicates that the configuration is successful ! [image.png ](http://upload-images.jianshu.io/upload_images/5811881-c473853017951ebe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

maven directory

![image.png ](http://upload-images.jianshu.io/upload_images/5811881-8a4c77bcc9a4565a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

  • bin directory:
    This directory contains scripts run by mvn. These scripts are used to configure java commands, prepare classpath and related Java system properties, and then execute Java commands.
  • Boot directory:
    This directory contains only one file, which is plexus-classworlds-2.5.2.jar. Plexus-classworlds is a class loader framework. Compared with the default java class loader, it provides a richer syntax to facilitate configuration. Maven uses this framework to load its own class libraries.
  • conf directory:
    This directory contains a very important file settings.xml. Modify the file directly, you can customize the behavior of Maven globally on the machine. Generally, we prefer to copy the file to the ~/.m2/directory (~ represents the user directory), and then modify the file. The scope customizes the behavior of Maven.
  • lib directory:
    This directory contains all the Java class libraries required by Maven runtime. Maven itself is developed in modules, so users can see files such as maven-core-3.0.jar, maven-model-3.0.jar, etc. In addition, there are also some third-party dependencies used by Maven, such as commons-cli-1.2.jar, commons-lang-2.6.jar and so on.

Maven common command description

    mvn clean target 
    mvn clean compile target 
    mvn clean test 
    mvn clean package 
    mvn clean install 
    mvn clean deploy  

Most of the above commands are written consecutively, and you can split them and execute them separately. This is alive. Depending on your personal preferences and usage requirements, Eclipse Run as will provide commonly used commands for maven projects.

Maven use

    <?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>
        <groupId>com.tengj</groupId>
        <artifactId>springBootDemo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springBootDemo1</name>
    </project>
 

The first line of the code is the XML header, which specifies the version and encoding of the xml document. Project is the root element of all pom.xml. It also declares some POM-related namespaces and xsd elements. The first child element modelVersion under the root element specifies the current POM model version. For Maven3, it can only be the 4.0.0 code. The most important thing is to include groupId, artifactId and version. These three elements define the basic coordinates of a project. In the Maven world, any jar, pom or jar is distinguished based on these basic coordinates.

The groupId defines which group the project belongs to, and can be named arbitrarily. For example, the myapp project of Google is named com.google.myapp

artifactId defines the unique ID of the current Maven project in the group, such as defining hello-world.

version specifies the current version of the project 0.0.1-SNAPSHOT, SNAPSHOT means snapshot, indicating that the project is still under development and is unstable.

The name element provides a more user-friendly project name. Although this is not necessary, it is recommended to declare a name for each POM to facilitate information exchange

%E4%BE%9D%E8%B5%96%E7%9A%84%E9%85%8D%E7%BD%AE "Dependent Configuration") Dependent Configuration

    <project>
    ...
    <dependencies>
        <dependency>
            <groupId> </groupId>
      <artifactId> </artifactId>
      <version> </version>
      <type> </type>
      <scope> </scope>
      <optional> </optional>
      <! -->
      <exclusions>
          <exclusion>
         <groupId> </groupId>
      <artifactId> </artifactId>
     </exclusion>
      </exclusions>
     </dependency>
    <dependencies>
    ...
    </project> 

The dependencies under the root element project can contain one or more dependency elements to declare one or more project dependencies. The elements that each dependency can contain are:

  • The basic coordinates of grounpId, artifactId and version: For any dependency, the basic coordinates are the most important, and Maven can find the required dependencies based on the coordinates.
  • type: dependent type, packaging defined for project coordinates. In most cases, this element does not need to be declared, and its default value is jar
  • scope: dependent scope
  • optional: Whether the mark dependency is optional
  • exclusions: used to exclude transitive dependencies
%E4%BE%9D%E8%B5%96%E8%8C%83%E5%9B%B4 "Dependency Range") Dependency Range

The dependency scope is used to control the relationship between dependencies and the three classpaths (compile classpath, test classpath, and run classpath). Maven has the following dependency scopes:

  • compile: Compile the dependency range. If not specified, the dependency range will be used by default. The Maven dependency using this dependency scope is valid for the three classpaths of compiling, testing, and running. A typical example is spring-code, which needs to be used when compiling, testing, and running.
  • test: Test dependency range. The Maven dependency that uses the secondary dependency scope is only valid for the test classpath, and this dependency cannot be used when compiling the main code or running the project. A typical example is Jnuit, which is only needed when compiling the test code and running the test.
  • provided: The scope of dependency has been provided. The Maven dependency that uses this dependency scope is valid for compiling and testing the classpath, but it is invalid at runtime. A typical example is servlet-api. This dependency is required when compiling and testing the project, but when running the project, due to the container and provisioning, there is no need for Maven to introduce it repeatedly.
  • runtime: The runtime depends on the scope. The Maven dependency that uses this dependency scope is valid for testing and running the classpath, but it is invalid when compiling the main code. A typical example is the implementation of the JDBC driver. The compilation of the main code of the project only requires the JDBC interface provided by the JDK, and the specific JDBC driver that implements the above interface is only required when testing or running the project.
  • system: System dependency range. The relationship between the dependency and the three classpaths is exactly the same as the provided dependency range. However, when using the system-scoped dependency, the path of the dependent file must be explicitly specified through the systemPath element. Since such dependencies are not resolved through the Maven repository and are often bound to the native system, they may constitute a non-portable build, so they should be used with caution. The systemPath element can refer to environment variables, such as:
    
    <dependency>
        <groupId>javax.sql</groupId>
        <artifactId>jdbc-stdext</artifactId>
        <Version>2.0</Version>
        <scope>system</scope>
        <systemPath>${java.home}/lib/rt.jar</systemPath>
    </dependency> 
  • import: Import the dependency range. The scope of dependence will not have an actual impact on the three classpaths.
    The relationship between the above-mentioned various dependency scopes other than import and the three classpaths is as follows:

![image.png ](http://upload-images.jianshu.io/upload_images/5811881-e7cdb7800f523b6b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

Transitive dependence

For example, for an account-email project, account-email has a compile-scoped spring-code dependency, and spring-code has a compile-scoped commons-logging dependency, then commons-logging will become account-email's compile scoped dependency , Commons-logging is a transitive dependency of account-email ! [image.png ](http://upload-images.jianshu.io/upload_images/5811881-e406525e3a71de7f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

With the transitive dependency mechanism, there is no need to consider what it depends on when using the Spring Framework, and there is no need to worry about introducing redundant dependencies. Maven will parse each directly dependent POM, and introduce those necessary indirect dependencies into the current project in the form of transitive dependencies.

Dependent range

Assuming that A depends on B and B depends on C, we say that A is the first direct dependence on B, B is the second direct dependence on C, and A is transitive dependence on C. The scope of the first direct dependency and the second direct dependency determines the scope of the transitive dependency. As shown in the figure below, the leftmost row represents the first direct dependency range, the top row represents the second direct dependency range, and the intersecting cell in the middle is Represents the scope of transitive dependency.

![image.png ](http://upload-images.jianshu.io/upload_images/5811881-9e1e45b117656aac.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

From the above figure, we can find such a rule:

  • When the scope of the second direct dependency is compile, the scope of the transitive dependency is consistent with the scope of the first direct dependency;
  • When the scope of the second direct dependency is test, the dependency will not be passed;
  • When the scope of the second direct dependency is provided, only the dependencies whose scope of the first direct dependency is also provided are passed, and the scope of all transitive dependencies is also provided;
  • When the scope of the second direct dependency is runtime, the scope of the transitive dependency is the same as the scope of the first direct dependency, except for the compile column, at this time the scope of the transitive dependency is runtime.

Comparison of Maven and Gradle

There are three major build tools in the Java ecosystem: Ant, Maven and Gradle. Among them, Ant is maintained by the Apache Software Foundation; the word Maven comes from Yiddish (Jewish), which means the accumulation of knowledge, and was originally used in the Jakata Turbine project to simplify the construction process; Gradle is based on Apache Ant and The Apache Maven concept project automates the construction of open source tools. It uses a Groovy-based Domain Specific Language (DSL) to declare project settings, abandoning various cumbersome configurations based on XML.

After several years of development, Ant has almost disappeared, and Maven has gradually been forgotten due to its relatively inflexible configuration, and since Gradle is an optimized version based on Ant and Maven, it has become in full swing.

The main functions of Maven are mainly divided into dependency management system, multi-module construction, consistent project structure, consistent construction model and plug-in mechanism. Here are the differences between the two through these five aspects:

Dependency management system

In the Maven management system, a Coordination consisting of GroupID, ArtifactID, and Version is used to uniquely identify a dependency. Any project built on Maven itself must also define these three attributes. The generated package can be a Jar package, a War package or an Ear package.

A typical quote is as follows:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-data-jpa
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-thymeleaf
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-test
        <scope>test</scope>
    </dependency>
</dependencies>
 

Here GroupID is similar to namespace in C# or package in Java, while ArtifactID is equivalent to Class and Version is equivalent to different versions. If Version is omitted, the latest version link will be selected.

At the same time, the warehouses storing these components are divided into remote warehouses and local warehouses. The remote warehouses can use the world's public central warehouse or the private warehouse built by Apache Nexus; the local warehouse is on the local computer. Through the settings.xml file in the Maven installation directory, the path of the local warehouse and the remote warehouse address can be configured. Gradle uses Maven as a dependency management system in its design, and also introduces improvements to make dependencies more concise:

    dependencies {
   //This dependency is exported to consumers, that is to say found on their compile classpath.
    api 'org.apache.commons:commons-math3:3.6.1'
     
   //This dependency is used internally, and not exposed to consumers on their own compile classpath.
    implementation 'com.google.guava:guava:23.0' 
   //Use JUnit test framework
    testImplementation 'junit:junit:4.12' 
    compile 'org.hibernate:hibernate-core:3.6.7.Final'
    testCompile  junit:junit:4.+'
    
     
    } 

In addition, Maven and Gradle look at dependencies differently. In Maven, there are 6 scopes for a dependency, which are compile, provided, runtime, test, system, and import. Compile is the default. Gradle simplifies it into four types, compile, runtime, testCompile, and testRuntime. For example, the above code "testCompile'junit:junit:4.+'" supports dynamic version dependency in Gradle. Use the + sign after the version number to achieve dynamic version management. Gradle's implementation mechanism is more clear in terms of resolving dependency conflicts. Both use transitive dependencies. If multiple dependencies point to different versions of the same dependency, it may cause dependency conflicts. Maven is more cumbersome to handle. Gradle inherently has a relatively clear strategy.

Multi-module construction

In a service-oriented architecture, a project is usually broken down into multiple modules. In Maven, the parent POM (Project Object Model) needs to be defined as a general configuration model for a group of modules, and tags can be used to define a group of submodules in the POM file. The build configuration and dependency configuration in the parent POM will be automatically inherited to the child module.

Gradle also supports multi-module construction. You can use the allprojects and subprojects code blocks in the parent's build.gradle to define the configurations applied to all projects or subprojects, respectively. The definitions in the submodules are placed in the settings.gradle file. Each module represents an object instance of the project. These objects can be manipulated through allproject or subprojects in the parent's build.gradle, which is more flexible than Maven.

    allprojects {
    task nice << { task -> println "I'm $task.project.name" }
    } 

Executing the command gradle -q nice will print out the project names of each module in turn.

Consistent project structure

Maven specifies a set of project directory structure as the standard java project structure, and Gradle also uses this standard directory structure. If the Maven project structure is used in the Gradle project, there is no need to perform redundant configuration in Gradle, just include apply plugin:'java' in the file, and the system will automatically identify the corresponding resources such as source, resource, test source, test resource, etc. .

At the same time, Gradle, as a build tool on the JVM, also supports the construction of Groovy, Scala and other source code. The same function Maven can achieve its purpose through some plug-ins, but Gradle is more flexible in configuration.

Consistent build model

In order to solve the problem of lack of standardization of project construction in Ant, Maven has set a standard project cycle. The construction cycle: verification, initialization, raw data generation, raw data processing, resource generation, resource processing, compilation, processing, and test raw data generation , Processing test raw data, generating test resources, processing test resources, test compilation, processing test classes, testing, predefined packages, generating package files, pre-integration testing, integration testing, post-integration testing, verification, installation, and deployment. But this build cycle is also a disadvantage of Maven applications. Because Maven restricts the project's build cycle too tightly, it is impossible to add new phases in the build cycle, and can only bind the plugin to the existing phases. Gradle is very flexible in the construction model. You can create a task and establish a dependency with an existing task through depends at any time.

Plug-in mechanism

Both use a plug-in mechanism. Maven is configured based on XML, while it is more flexible in Gradle.

Reference article

http://www.pianshen.com/article/4537698845https://www.jianshu.com/p/7248276d3bb5https://www.cnblogs.com/lykbk/p/erwerwerwerwerwe.htmlhttps://blog.csdn.net/u012131888/article/details/78209514https://blog.csdn.net/belvine/article/details/81073365https://blog.csdn.net/u012131888/article/details/78209514

WeChat public account

Personal public number: Huang Xiaoxie

Huang Xiaoxie is a 985 master of cross-examination software engineering. He taught Java for two years and obtained offers from nearly ten major manufacturers such as BAT. He has grown from a technical white to an Ali engineer.

The author focuses on the JAVA back-end technology stack, and is keen to share programmer dry goods, learning experience, job hunting experience and program life. At present, Huang Xiaoxie s CSDN blog has millions of+ visits, knows that fans are 2W+, and the entire network has 10W+ readers. .

Huang Xiaoxie is a slash young man who insists on studying and writing. He believes in the power of lifelong learning. He hopes to make friends with more programmers and make progress and growth together!

Original e-book: follow the official account [Huang Xiaoxie] and reply [original e-book] to receive my original e-book "Rookie Programmer Training Manual: From Technical Novice to Alibaba Java Engineer"

3T technical learning resources for programmers : some great gift packages of technical learning resources for programmers. After paying attention to the official account, you can get it for free by replying to the keyword "information" in the background .

PubMed review the information: Computer PubMed spree, are some of the review materials for my own use when PubMed review, including public courses and professional video review, recommend it to everyone here, the number of public attention, background replies keyword "PubMed" that is, Available for free.

Technical public number: Java technology arena

If you want to follow my updated articles and shared dry goods in real time, you can follow my public account [Java Technology Jianghu] A technical station of an Ali Java engineer, author Huang Xiaoxie, focusing on Java related technologies: SSM, SpringBoot , MySQL, distributed, middleware, cluster, Linux, network, multithreading, occasionally talk about Docker, ELK, but also share technical dry goods and learning experience, committed to Java full-stack development!

Essential learning resources for Java engineers : Some commonly used learning resources for Java engineers, after paying attention to the official account, you can get them for free and no routines by replying to the keyword "Java" in the background .