Five minutes to quickly grasp the core concepts of maven

Time:2021-1-24

Focus on “Java back end technology stack”

Reply to “interview” for full interview information

Two days ago, in a technology group, someone was still asking about the meaning of the keywords groupid, artifactid and version in Maven. Therefore, I think it is necessary to talk about these core concepts in Maven.

Success is not only in the future, but from the moment you decide to do it, it is accumulated continuously.

Today we are going to learn the core concepts in Maven. After understanding these core concepts, we can learn and use Maven at a deeper level.

Five minutes to quickly grasp the core concepts of maven

coordinate

The concept of coordinates

From Baidu Encyclopedia

One or a group of numbers that can determine the position of a point in space is called the coordinates of the point. It is usually expressed by the distance from this point to several fixed lines that intersect vertically. These lines are called axes. The number of axes is 2 (x, y) in plane and 3 (x, y, z) in space.

Five minutes to quickly grasp the core concepts of maven

In fact, it can identify the only point in the plane or space.

Coordinates in maven

One of the core functions of Maven is to manage project dependencies and introduce various jar packages we need. In order to automatically parse any Java component, Maven must uniquely identify these jar packages or other resources, which is the basis of managing project dependencies, that is, coordinates. Projects developed by ourselves should also be uniquely identified by coordinates, so that they can be referenced in other projects.

case

Dependency time: for example, we rely on JUnit’s jar package.

<!--  pom.xml Medium -- >
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>

In the project definition, our project will be typed as jar or war package.

<?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.tian</groupId>
        <artifactId>maven-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <! -- the default is jar -- >
        <packaging>jar</packaging>
</project>

The last type of jar or war:

artifactid-version.jar
artifactid-version.war

The packaging label is jar by default, so usually when we don’t specify whether to type as jar package or war, the final type is jar package.

Composition of Maven coordinates

「groupId」Organization identification (package name). Defines the actual project to which the current Maven project belongs. First, the Maven project and the actual project are not necessarily one-to-one. For example, there are many Maven projects corresponding to spring framework, such as spring core, spring context, etc. This is due to the concept of modules in maven, so an actual project is often divided into many modules. Secondly, the groupid should not correspond to the organization or company to which the project belongs. The reason is very simple. There are many actual projects in an organization. If groupid is only defined at the organization level, and we will see later that artifactid can only define Maven projects (modules), then the actual project level will be difficult to define. Finally, the expression of groupid is similar to that of java package name, and usually corresponds to domain name one by one. In the above example, if the groupid is JUnit, does it feel special? This is OK, because there is only JUnit in the world, and it doesn’t have many branches.

「artifactId」Project name. This element defines a maven project (module) in the current actual project. It is recommended to use the actual project name as the prefix of artifactid. For example, JUnit in the above example is the actual project name, which is convenient and intuitive. By default, components generated by Maven will take artifactid as the file header, such as junit-3.8.1.jar, and use the actual project name as the prefix, so that the components of a project can be easily found from the local warehouse.

「version」The current version of the project or the version of the jar we are relying on. This element defines the version of the component to be used. For example, the version of JUnit in the above example is 3.8.1. You can also change it to 4.0 to use JUnit in 4.0.

「packaging」The most common ways to package a project are jar and war. The default is jar. Define how Maven projects are packaged and what packages of components are used. First, the packaging method usually corresponds to the file extension of the generated component. If there is no packaging in the above example, the default is jar package, and the final file name is junit-3.8.1.jar. It can also be packaged as war and so on.

「classifier」This element is used to help define some attachments to build the output. The subsidiary component corresponds to the main component. For example, the main component in the above example is junit-3.8.1.jar. The project may also be generated through some plug-ins, such as junit-3.8.1- javadoc.jar ,junit-3.8.1- sources.jar In this way, the accessory component has its own unique coordinates.

Among the above five elements, groupid, artifactid and version must be defined, packaging is optional (jar by default), and classfilter cannot be defined directly, so it needs to be used in combination with plug-ins.

Why does Maven use coordinates?

  • There are a lot of builds in the Maven world, so we need to find a uniform specification to uniquely identify a build.
  • With a unified specification, the search work can be handed over to the machine.

Maven dependency management

rely on

Dependence is usually manifested as: I need your things, just like the mutual dependence between lovers, the mutual dependence between husband and wife, people depend on water, people depend on food and so on.

In maven, each class of b.jar package is used in the project, and the project relies on b.jar.

The complex relationship is multi-layer dependency: a.jar package depends on b.jar package, and possibly b.jar package depends on c.jar. This phenomenon can also be called dependency transitivity.

Five minutes to quickly grasp the core concepts of maven

Our project relies indirectly on b.jar.

Dependency configuration

The dependency configuration cases in Maven are as follows:

<! -- add dependency configuration -- >
<dependencies>
  <! -- the project will use JUnit's jar package, so add JUnit's jar package dependency here -- >
  <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.9</version>
      <scope>test</scope>
  </dependency>
  <! -- the project will use Hello's jar package, so add the dependency of Hello's jar package here -- >
  <dependency>
      <groupId>com.tian.maven</groupId>
      <artifactId>user-service</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      < scope > compile < / scope > <! -- dependency range -- >
  </dependency>
</dependencies>

Scope of dependence

The so-called dependency scope refers to where we need to rely on jar. Some need to compile, some need to test, etc.

There are six kinds of dependency scopes

「compile」Default compilation dependency scope. It is effective to compile, test and run three kinds of classpath. That is to say, the dependent jar package should be used in compiling, testing and running;

「test」Test dependency scope. Only valid for testing classpath. This kind of dependency cannot be used when compiling and running a project. The typical one is JUnit, which is only needed when compiling test code and running test code;

「provided」Dependency scope provided. The classpath of the test is valid for compilation, but not for runtime. Because it’s already provided by a container, such as a servlet- api.jar , which needs to be used in compilation and testing, but when running, the web container has been provided, so Maven is not needed to help introduce it.

「runtime」Run time dependency range. The Maven dependency of this dependency range is valid for compiling tests, running tests and the classpath of running projects, but it is invalid when compiling the main code. For example, jdbc driver implementation is required when running.

「system」System dependency range. When using system dependency, the path of the dependency file must be explicitly specified through the SystemPath element. It does not rely on Maven warehouse parsing. Therefore, the construction may not be portable (that is, it may not be a problem on your computer, but it is not clear on other people’s computers). It is a bit similar to provided. Pay attention to the careful use of this system.

<systemPath>${java.home}/lib/rt.jar</systemPath>

「import」Only POM supports this scope on the type dependencies in this section. It indicates that the dependency will be replaced by a list of valid dependencies in the specified POM section. Because they have been replaced, the dependency import with the scope will not actually participate in limiting the transitivity of the dependency, which is more used in springboot and springcloud.

Among the above six ranges, compile, test, runtime and provided are commonly used.

The dependency range can not only control the relationship with the three Classpaths, but also affect the transitive dependency

Five minutes to quickly grasp the core concepts of maven

“Attention”This is expected to be run-time scope, so all compilation dependencies must be explicitly listed. However, if the library you rely on extends a class from another library, both must be available at compile time. Therefore, even if compile time dependencies are transitive, they remain in the compile scope.

Maven warehouse management

Maven warehouse

It is used to store all Maven shared builds in a unified way. To put it bluntly, it is used to store jar packages. It is impossible to compile without corresponding jar packages when we compile locally. We need a lot of jar dependencies in a project. At this time, we know the importance of the warehouse.

Maven warehouse layout

According to Maven coordinates, the unique storage path of each build in the warehouse is defined

groupId/artifactId/version/artifactId-version.packaging

Local warehouse

In the previous article, each user has only one local repository. The default is ~ /. M2 / repository /, which represents the user directory. In order to facilitate management, they usually set up their own directory to store the contents of the local warehouse. In this way, when we develop, we will directly go to our local repository to find the jar, if not, we will pull it from the central repository.

Central warehouse

Basically, all jar packages for external development are saved. Maven’s default remote warehouse, (foreign website) URL address:http://search.maven.org/. There are also Alibaba’s warehouses. When we developed them, many people liked to use them because of the networkhttp://maven.aliyun.com

At this time, the relationship between our local warehouse and the central warehouse is as follows:

Five minutes to quickly grasp the core concepts of maven

Private service

Most companies will build private service, which is a kind of special remote warehouse, which is set up in the local area network. For example, the company builds a LAN, the company also builds a warehouse, and then the developers directly use the private services built by the company, which greatly reduces the network overhead and development costs (sometimes the access to the external network is very slow, which will waste everyone’s development time).

In this way, every time developers need each jar package, they will directly pull it from the company’s private server. They don’t need to use the Internet to pull it from the central warehouse. All in all, save time and save network. And some enterprises still do not give the Internet, at this time you know the importance of this private service.

After adding private service, the relationship diagram of local warehouse + private service + central warehouse is as follows:

Five minutes to quickly grasp the core concepts of maven

During the interview, I was frequently asked: what is the relationship between local warehouse, private service and central warehouse?

Maven life cycle

Maven’s life cycle: from the construction of our project to the release of the project.

Five minutes to quickly grasp the core concepts of maven

Description of each stage:

Five minutes to quickly grasp the core concepts of maven

In order to complete the default lifecycle, these phases (including other lifecycle phases not listed above) will be executed sequentially.

Maven has three standard life cycles:

  • Clean lifecycle does some cleaning up before it actually builds.
  • Default lifecycle is the core part of building, compiling, testing, packaging, deployment and so on.
  • Site lifecycle generates project reports, sites and publishes sites.

These three standards are independent of each other. You can just call clean to clean up the working directory and just call site to generate the site. Of course, you can also run MVN clean install site directly to run all three life cycles.

When running any phase, all the previous phases will be run, which is why when we run MVN install, the code will be compiled, tested and packaged. In addition, Maven’s plug-in mechanism is completely dependent on Maven’s lifecycle, so understanding the lifecycle is crucial.

Maven plug in

Maven doesn’t do specific things. It only specifies the stages and steps of the life cycle, which are completed by plug-ins integrated into Maven.

  1. The core of Maven only defines the abstract life cycle, and the specific tasks are completed by plug-ins.
  2. Each plug-in can realize multiple functions, and each function is a plug-in target.
  3. Maven’s life cycle and plug-in target are bound to each other to complete a specific construction task. For example, compile is a plug-in target of Maven compiler plugin.

About plug-ins, let’s give you a general idea. A follow-up article will be published specifically for Maven plug-ins.

Exclude unnecessary dependencies

<dependency>
    <groupId>com.tian.maven</groupId>
    <artifactId>my-maven</artifactId>
    <version>1.0.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.tian.maven</groupId>
            <artifactId>your-maven</artifactId>
        </exclusion>
    </exclusions>
</dependency>

The exclusion element is used above to exclude the passing of my Maven > your Maven dependency, that is, my Maven > your Maven will not be passed to the current project.

There can be multiple exclusion elements in exclusions, and one or more dependent passes can be excluded. When declaring an exclusion, you only need to write groupid and artifactid, and the version can be omitted.

summary

This article describes Maven coordinates, Maven dependency management, Maven warehouse management, Maven life cycle, and gives a brief introduction to Maven plug-ins. With these concepts as a cushion, we can have a deeper understanding of why we use them in the studio.

“As long as the road is right, we are not afraid of a long way. 」

Recommended reading

Interviewer series: About integer cache range

Interviewer: what do you think of serialization

To solve these 24 JVM interview questions, you have the strength to ask 30K~