Mind map
Maven and construction
What is Maven
Accumulation of knowledge, experts and experts. Cross platform project management tools. Open source project organized by Apache. It mainly serves project construction, dependency management and project information management based on Java platform.
Similar to yum and apt on linux platform, npm in front-end field. Maven was formerly Ant. At present, the source code of tomcat is built and managed with Ant. More advanced tools include Gradle and Spring project.
What is build
What is build: the process of compiling, running unit tests, generating documents, packaging and deploying is build.
Steps to build:
-
clean up: delete the old class bytecode file compiled previously.
-
Compile: compile the java source program into a class bytecode file.
-
Test: automatic test, automatically call junit program.
-
report: the results of the test program execution.
-
Package: War package for dynamic Web project and jar package for java project.
-
install: copy the packaged files to the specified location in the "warehouse" (Maven specific concept).
-
deploy: copy the war package generated by the dynamic Web project to the Servlet container so that it can run.
Project skeleton
pom: Project Object Model
Root directory: project name |---src: Source code |---|---main:main program |---|---|---java: Main program code path |---|---|---resource: Main program configuration file path |---|---test: test |---|---|---java: Test code path |---|---|---resource: Test profile path |---pom.xml: maven configuration file
Simple demonstration
## one use archetype Command generation maven Simple skeleton mvn archetype:generate -DarchetypeCatalog=internal ## two Compile the currently generated project mvn compile ## three Use other commands mvn test-compile mvn package mvn clean mvn install mvn depoly Not for the time being
Coordinates and dependencies
What are coordinates
In analogy to plane geometry in mathematics, any coordinate (x, y) can uniquely identify a point in the plane.
This point corresponds to maven, which is the file of. jar,. war and other files.
Maven use groupId,artifactId,version,packaging,classifier And other elements to form their own coordinates, and define a set of such rules. As long as the correct coordinate element can be provided, Maven can find the corresponding component.
Coordinate element
-
groupId: defines the actual project to which the current Maven project belongs.
-
artifactId: defines a Maven project (module) in the actual project.
-
packaging: defines how Maven projects are packaged. jar,war,pom. The default is jar.
-
Version: defines the current version of the Maven project.
-
classifier: distinguish components with different contents built from the same artifact.
classifier usage scenario
Distinguish packages based on different JDK versions
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.2</version> <classifier>jdk13</classifier> <!--<classifier>jdk15</classifier>--> </dependency>
Distinguish between different components of the project
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.2</version> <classifier>jdk15-javadoc</classifier> <!--<classifier>jdk15-sources</classifier> --> </dependency>
The component name corresponds to the coordinate. The general rule is: artifactid version [- classifier]. Packaging.
Dependency declaration
<dependencies> <dependency> <groupId></groupId> <artifactId></artifactId> <version></version> <type></type> <optional></optional> <exclusions> <exclusion> <artifactId></artifactId> <groupId></groupId> </exclusion> ... </exclusions> </dependency> ... </dependencies>
-
groupId, artifactId, version: the dependent basic coordinates.
-
Type: the type of dependency. It corresponds to the packaging corresponding to the project. Generally, it does not need to be declared.
-
Scope: the dependent scope, which will be explained later.
-
Optional: mark whether the dependency is optional.
-
exclusions: used to exclude transitive dependencies.
Dependency range
-
Compile: compile dependency range
If not specified, the dependency range is used by default. The three Classpaths are valid for compiling, testing and running. For example, spring core.
-
test: test dependency range
It is only valid for testing classpath. It is only required when compiling and running tests. It will not be typed in when packaging. Such as JUnit.
-
Provided: dependency range provided
classpath is valid for compilation and testing, but not for runtime. For example, servlet API is required when compiling and testing projects, but in actual operation, the container has been provided, and there is no need for repeated maven references.
-
Runtime: runtime dependency range
The classpath is valid for testing and running, but not when compiling the main code. For example, the implementation package of jdbc driver. Specific JDBC drivers are required only when executing tests or running projects.
-
System: system dependency range
It is exactly the same as the provided dependency range, but when using this range, 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, the build may not be portable, so they should be used with caution. The systemPath element can reference environment variables, such as:
<dependencies> <dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-stdxt</artifactId> <version>2.0</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency> </dependencies>
-
Import: import dependency range
It only takes effect in the dependency management tab and imports the content of the dependency management node in the defined pom file
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>4.3.16.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Dependency mechanism and characteristics
Dependency delivery
-
A - > b (compile): the first direct dependency
-
B - > C (compile): the second direct dependency
-
A - > C (compile): transitive dependency
When configured in A
<dependency> <groupId>com.B</groupId> <artifactId>B</artifactId> <version>1.0</version> </dependency>
The C package is automatically imported.
The scope of transitivity dependency is shown in the following figure:
Dependent mediation
When there is a problem with transitive dependency, you can clearly know which dependency path the transitive dependency is introduced from.
1, Principle of the shortest path first
-
A->B->C->X(1.0)
-
A->D->X(2.0)
Since only one version of package can be imported, import X(2.0) according to the shortest path
2, Principle of first declaration priority
-
A->B->Y(1.0)
-
A->C->Y(2.0)
At this time, since the length of dependent paths is consistent, the first declaration takes precedence. On the premise of consistent path length, if the declaration order of B dependency in POM file is before that of C dependency, Y(1.0) will be introduced. The following dependencies can be used for testing:
<dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.4.1</version> <exclusions> <exclusion> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> <exclusions> <exclusion> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> </dependencies>
Here is a point that needs special attention. See the following dependencies:
<dependencies> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.11</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> </dependencies>
According to two principles, the expected result should be that the build of version 1.11 will be relied on. But the actual results rely on version 1.10. what! Isn't this a violation of maven's first definition principle of relying on mediation?
In fact, this is the function of the dependency plug-in. By default, the replication strategy is adopted. When the build declaration is in the same pom and the groupid is consistent with the artifact ID, the latest declaration shall prevail, and the later ones overwrite the previous ones.
Note that the function of relying on mediation is not involved here. My understanding is that dependency mediation only occurs when building from different POMs. At this time, the build declaration is in the same pom, so dependency mediation will not be triggered.
Optional dependency
A - > b, B - > x (optional), B - > y (optional).
Project A depends on project B, and project B depends on projects X and Y.
In theory, project A will rely on projects B, X and Y.
However, X and Y dependencies may be mutually exclusive to B. for example, B is a database isolation package that supports multiple databases MySQL and Oracle. These two databases need to be supported when building B project, but only one database will be relied on when using this toolkit.
At this time, you need to declare X and Y as optional dependencies in the B project pom file, as follows:
<dependency> <groupId>com.X</groupId> <artifactId>X</artifactId> <version>1.0</version> <optionnal>true</optionnal> </dependency> <dependency> <groupId>com.Y</groupId> <artifactId>Y</artifactId> <version>1.0</version> <optionnal>true</optionnal> </dependency>
After being identified with the optionnal element, it will only affect the current project B. when other projects depend on project B, these two dependencies will not be passed.
Project A depends on project B. if the actual application database is x, the X dependency needs to be explicitly stated in A's pom.
Warehouse
Warehouse classification: including local warehouse and remote warehouse. The remote warehouse includes private server and central warehouse. Search build order:
-
Local warehouse
-
repository in maven settings profile;
-
The repository defined in the profile in pom.xml;
-
Repositories in pom.xml (found in the order of definition);
-
maven settings mirror;
-
Central central warehouse;
life cycle
Maven's life cycle is to abstract and unify all construction processes, including almost all construction steps such as project cleaning, initialization, compilation, testing, packaging, integration testing, verification, deployment and site generation.
Maven's life cycle is abstract and does not do any practical work. The actual tasks are left to the plug-in.
This means that Maven only defines the overall structure of the algorithm in the parent class, and the child class controls the actual behavior by overriding the method of the parent class (Template Method in design pattern). The pseudo code is as follows:
public abstract class AbstractBuilder { public void build() { init(); compile(); test(); package(); integrationTest(); deploy(); } protected abstract void init(); protected abstract void compile(); protected abstract void test(); protected abstract void package(); protected abstract void integrationTest(); protected abstract void deploy(); }
Three life cycles
Maven's life cycle is not a whole. Maven has three sets of independent life cycles: clean, default and site.
-
clean The purpose of the life cycle is to clean up the project;
-
default The purpose of the life cycle is to build the project;
-
site The purpose of the life cycle is to establish the project site;
Single life cycle execution sequence
Each life cycle contains some phases, which are sequential, and the subsequent phases depend on the previous phases.
Take the clean life cycle as an example. It includes pre clean, clean and post clean phases. When pre clean is called, only the pre clean phase can be executed;
When clean is called, the pre clean and clean phases are executed sequentially, and so on.
Relationship between life cycles
The three sets of life cycles are independent of each other. Users can call only a certain stage of the clean life cycle or only a certain stage of the default life cycle without any impact on other life cycles.
For example, when a user invokes the clean phase of the clean lifecycle, no phase of the default lifecycle is triggered, and vice versa.
Detailed explanation of each stage of the life cycle
clean
Life cycle phase | describe |
---|---|
pre-clean | Perform some work that needs to be done before cleaning. |
clean | Clean up the files generated by the last build. |
post-clean | Perform some work that needs to be done after cleaning. |
default
There are 23 stages, and only the key steps are introduced here, as shown in the table below:
Life cycle phase | describe |
---|---|
validate | Check whether the project configuration is correct and whether all necessary information for completing the construction process can be obtained. |
initialize | Initializes the build state, such as setting properties. |
generate-sources | |
process-sources | Process the project resource file and the project master resource file. Generally speaking, the contents of src/main/resources directory are copied to the main classpath directory of the project output after variable replacement. |
generate-resources | |
process-resources | |
compile | Compile the main source code of the project. Generally speaking, compile the java files in src/main/java directory to the main classpath directory of the project output. |
process-classes | Handle compiled files, such as Java Class bytecode enhancement and optimization. |
generate-test-sources | |
process-test-sources | Process project test resource files. Generally speaking, the contents of src/test/resources directory are copied to the test classpath directory output by the project after variable replacement. |
test-compile | Compile the test code for the project. Generally speaking, compile the java files in src/test/java directory to the test classpath directory of the project output. |
process-test-classes | |
test | Run tests using an appropriate unit test framework, such as JUnit. |
prepare-package | Before the actual packaging, do whatever is necessary to prepare the packaging. |
package | Get the compiled code and package it in a publishable format, such as JAR, WAR or EAR files. |
pre-integration-test | Perform the required actions before the integration test is executed. For example, set the required environment variables. |
integration-test | Process and deploy the necessary engineering packages into the environment where the integration test can run. |
post-integration-test | Perform the necessary operations after the integration test is executed. For example, clean up the environment. |
verify | Run inspection operations to verify that the work package is effective and meets quality requirements. |
install | Install the project package into the local warehouse, which can be used as a dependency of other local projects. |
deploy | Copy the final project package to the remote warehouse for sharing with other developers and projects. |
site
Life cycle phase | describe |
---|---|
pre-site | Perform some work that needs to be done before building the project site. |
site | Generate project site documents. |
post-site | Perform some work that needs to be done after building the project site. |
site-deploy | Publish the generated project site to the server. |
plug-in unit
Maven's three sets of life cycle definitions do not do any actual work in each stage. The actual work is completed by the plug-in, and each life cycle stage is completed by the goal of the plug-in. Declare the following in the pom file (package the source file plug-in):
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.1</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Plug in target
A plug-in may have multiple functions, and each function is a target. For example, Maven dependency plugin has more than ten goals, and each goal corresponds to a function.
The targets of the plug-in are dependency:analyze, dependency:tree, and dependency:list.
General writing method: the prefix of the plug-in is before the colon, and the target of the plug-in is after the colon. For example, compiler:compile.
Plug in binding
Built in binding
For fast build, Maven has a set of built-in plug-in bindings. The three sets of life cycle plug-in bindings are as follows (in fact, they are the binding between each life cycle stage and the goal of the plug-in).
The construction method of default life cycle is related to its packaging type, which is specified in POM packaging. There are generally two types: jar and war. The following is the relationship between the default binding plug-in and the life cycle:
Custom binding
Custom binding allows us to control the combination of plug-in objectives and life cycle. Take the source jar that generates the main code of the project as an example.
The plug-in used and its target are Maven source plugin: jar no fork. Bind it to the default life cycle stage verify (any stage of three sets of life cycles can be specified arbitrarily).
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.1</version> <executions> <execution> <id>attach-sources</id> <!-- Specifies which phase of the lifecycle the action is in --> <phase>verify</phase> <goals> <!-- Specify which targets to execute the binding plug-in --> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Plug in configuration
-
Use command line configuration
Add the - D parameter to the maven command with a parameter key = parameter value to configure the plug-in target parameters.
For example, the Maven surefire plugin provides a maven.test.skip parameter. When the value is true, the test execution will be skipped:
-- contrast mvn install mvn install –Dmaven.test.skip=true
-
Use pom global configuration
When declaring a plug-in, make a global configuration for the plug-in, and all subsequent users of the plug-in should follow this configuration. For example, specify Maven compile plugin to compile the source file of version 1.7:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <fork>true</fork> <source>1.7</source> <target>1.7</target> </configuration> </plugin>
Aggregation and inheritance
Aggregation: in order to build multiple project modules at one time, you need to aggregate multiple project modules
<modules> <module>Module I</module> <module>Module II</module> <module>Module III</module> </modules>
Inheritance: in order to eliminate duplication, many of the same configurations are extracted, such as dependency, grouptId, version, etc
<parent> <groupId>com.xxxx.maven</groupId> <artifactId>parent-project</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../ParentProject/pom.xml</relativePath> </parent>
The following elements can be inherited:
-
groupId, project group ID;
-
Version, project version;
-
Description, item description information;
-
Organization, organization information of the project;
-
Inception year, the year when the project was founded;
-
developers, project developer information;
-
contributors, the contributor information of the project;
-
Distribution management, project deployment information;
-
Issue management, defect tracking system information of the project;
-
ciManagement, continuous integration system information of the project;
-
scm, version control system information of the project;
-
mailingLists, mailing list information of the project;
-
Properties, custom Maven properties;
-
dependencies, the dependency configuration of the project;
-
Dependency management, the dependency management configuration of the project;
-
repositories, warehouse configuration of the project;
-
build, including source directory configuration, output directory configuration, plug-in configuration, plug-in management configuration, etc;
-
reporting, including report output directory configuration and report plug-in configuration of the project.
Note that the following elements cannot be inherited:
-
artifactId
-
name
-
prerequisites
Relationship between aggregation and inheritance
-
The common point between the two is that the playing method must be pom
-
In a real project, a pom is both an aggregate pom and a parent pom
Note: the dependencies introduced by using dependencies in the parent pom will also be inherited by the child pom, so do not put too many actual dependencies on the parent pom. The parent pom is only used for management and uses the dependency management tag.
Flexible construction
Use properties, resources plug-in resource filter function and Maven's profile function to realize flexible environment switching
attribute
Through the properties element, users can customize one or more Maven attributes, and then use ${attribute name} to reference the attribute elsewhere in pom. The greatest significance of this method is to eliminate duplication.
1, Built in properties
-
${basedir} Represents the root directory of the project, that is, the directory containing the pom.xml file
-
${version} Equivalent to Or {pom.version} indicates the project version
2, POM properties
All elements in POM can use project. For example, ${project.artifactId} corresponds to the value of < project > element. Common POM attributes include:
-
${project.build.sourceDirectory} : The main source directory of the project. The default is src/main/java /
-
${project.build.testSourceDirectory} : The test source directory of the project. The default is / src/test/java /
-
${project.build.directory} : Project build output directory, default to target /
-
${project.build.outputDirectory} : The project main code compilation output directory is target/classes /
-
${project.build.testOutputDirectory} : The project test code compilation output directory is target/testclasses /
-
${project.groupId}: groupId of the project
-
${project.artifactId} : Artifactid of the item
-
${project.version} : Version of the project, equivalent to ${version}
-
${project.build.finalName} : The name of the project packaging output file. The default is $ {project.artifactId}${project.version}
3, Custom properties
Custom Maven attribute under element in pom
<properties> <swagger.version>2.2.2</swagger.version> </properties> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency>
4, Settings properties
All settings in settings.xml can be set through settings. Prefix reference is the same as POM attribute.
For example, ${settings.localRepository} points to the address of the user's local warehouse
5, Java system properties
All Java system properties can be referenced using Maven properties. For example, ${user.home} points to the user directory.
You can view all Java system properties from the command line mvn help:system
6, Environment variable properties
All environment variables can be referenced using the Maven attribute starting with env. For example, ${env.JAVA_HOME} refers to Java_ The value of the home environment variable.
You can also view all environment variables from the command line mvn help:system.
7, Parent project properties
The variables in the pom of the parent project are prefixed quote. The version of the parent project can also refer to {parent.version}
Profile
The profile feature allows us to define multiple profiles, and then each profile corresponds to different activation conditions and configuration information, so as to achieve the effect of using different configuration information in different environments.
A profile can be declared in the following places:
-
m.xml: the profile declared here is only valid for the current project
-
User settings.xml: the profile in. m2/settings.xml is valid for the Maven project of the user
-
Global settings.xml: conf/settings.xml, which is valid for all Maven items on the machine
Example:
<project> ... <profiles> <profile> <id>dev</id> <properties> <active.profile>dev</active.profile> <key1>value1</key1> <key2>value2</key2> </properties> <!-- Default activation configuration --> <activation> <activeByDefault>true</activeByDefault> </activation> <!-- In this profile Dependency introduced under --> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.4.RELEASE</version> </dependency> <dependencies> <!-- In this profile Variable file to be loaded under --> <build> <filters> <filter>../profile/test-pre.properties</filter> </filters> </build> </profile> </profiles> ... </project>