preface
If all you know about Maven is how to add dependency packages, you really need to read what follows.
<dependencies>
<! -- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
</dependencies>
Copy the code
- Maven package dependencies, dependency passing, and the rules for dependency passing
- The scope of the dependent package
- How to resolve JAR package conflicts
- Project inheritance and aggregation
- Maven Life Cycle
- Maven plugin use and common commands
- Use of Maven private server
- How to publish jars
- Maven defines different configuration environments
- Maven – assembly – the plugin package
Maven
Maven and Gradle are the most popular project management tools for Java projects. Maven currently has a higher percentage of usage than Gradle. Just use Maven when deciding which management tool to use.
Projects are managed in Maven through the concept of the POM-Project Object Model. In Maven, each project is an object, and objects (projects) can be relied upon, inherited, and aggregated.
The project dependency package is repository.com
The dependency packages are stored in the Maven repository, and we need to download the JARS from the repository with the dependency coordinate information.
Coordinates: groupId, artifactId, Version
When we introduce an A.jar in pop.xml, Maven will look for a.jar from the local repository, and if it doesn’t, it will download it from the central repository to the private server, and then download it from the local repository.
Depend on the transfer
Maven – a. ar rely on maven – b.jar
Maven – b.jar rely on maven – SAN Antonio ar
Maven-b. jar and maven-c.jar will be introduced in the maven-client project.
Dependency delivery follows two rules
Shortest path principle
There is dependency passing, but there is a problem.
Maven – a. ar rely on maven – b.jar
Maven – b.jar rely on maven – SAN Antonio ar (2.0)
Maven – a. ar rely on maven – SAN Antonio ar (1.0)
Maven-a.jar was introduced in the Maven-client project.
Which Maven will be adopted? – C. Jar
So one of the rules maven relies on is the shortest path principle.
– a – > b > c (2.0)
A – > c (1.0)
The Maven-Client project ended up using C of 1.0.
Be the first to declare principles
There is a problem with the shortest path principle. What to do when the shortest paths are the same? The first declaration of the principle is the sound effect when the shortest paths are the same.
Maven-a.jar and Maven-b.jar are introduced in the Maven-client project
Maven-b.jar only relies on Maven-c.jar (2.0)
Maven-a.jar only depends on Maven-c.jar (1.0)
Now it depends on the same shortest path
Maven-client -> Maven-a -> Maven-c (1.0)
Maven-client -> Maven-b -> Maven-c (2.0)
Maven-a was first introduced in Maven-client so Maven-c 1.0 sound effect
Maven-b was first introduced in Maven-client so Maven-c 2.0 sound effect
The first statement is a little short of our expectations. I can solve it this way.
- The first is to break the shortest dependency path and run it directly in
maven-client
Bring in what you wantmaven-c
Version.
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-a</artifactId>
<version>1.0 the SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-b</artifactId>
<version>1.0 the SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-c</artifactId>
<version>1.0 the SNAPSHOT</version>
</dependency>
</dependencies>
Copy the code
- The second is to exclude the JAR
This excludes maven-c passed by Maven-b. According to their own needs
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-a</artifactId>
<version>1.0 the SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-b</artifactId>
<version>1.0 the SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.example</groupId>
<artifactId>maven-c</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Copy the code
Dependent scope
The scope of a dependency defines when a JAR takes effect and whether it is packaged as a WAR or JAR.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
Copy the code
Different values of scope have different meanings.
compile
Scope Default value: compile indicates that the current dependent package is involved in compiling, running, testing, and packaging the project.
runtime
Runtime indicates that the runtime does not participate in project compilation, but in project running, testing, and packaging.
provided
The Provided identity is involved in compiling, running, and testing the project, but not in packaging.
system
System is used for some binary libraries we developed, but can not be published on the Internet, you can use this scenario to use. This jar is not packaged by default, so we need to configure it.
Participate in project compilation, running and testing.
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-d.jar</artifactId>
<version>1.0 the SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/lib/maven-d.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>${basedir}/lib</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</resources>
</build>
Copy the code
test
The test flag is only needed when compiling and running the test code, and is not included in the package.
import
Normally we would use this scope in the parent project. Represents the configuration of importing dependency from other POM.xml.
Our own parent project, for example, only wants Dependency management for SpringBoot.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Copy the code
Inheritance and aggregation
inheritance
Maven-client inherits Maven-Demo
<?xml version="1.0" encoding="UTF-8"? >
<project>
<parent>
<artifactId>maven-demo</artifactId>
<groupId>org.example</groupId>
<version>1.0 the SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>maven-client</artifactId>
</project>
Copy the code
The aggregation
Maven-demo aggregates five projects.
<?xml version="1.0" encoding="UTF-8"? >
<project >
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0. RELEASE</version>
<relativePath/> <! -- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>maven-demo</artifactId>
<packaging>pom</packaging>
<version>1.0 the SNAPSHOT</version>
<modules>
<module>maven-a</module>
<module>maven-b</module>
<module>maven-c</module>
<module>maven-client</module>
<module>maven-d</module>
</modules>
</project>
Copy the code
Inheritance is used to eliminate redundant configurations, such as some configuration package configurations, configuration variables, project dependencies, and plug-in dependent version management
Aggregation is used to quickly build projects.
To package a, B, C, D and clent before aggregation, run MVN package respectively.
After aggregation, we just need to run the MVN package under Maven-demo.
The life cycle
Maven has three internal build cycles. The clean, the default, site.
Where default is the life cycle we often use.
Clean Life cycle
Just do one thing: delete everything that was compiled.
Default Life Cycle
The default life cycle consists roughly of the following phases.
resources
-> compile
-> testResources
-> testCompile
-> test
-> package
-> install
-> deploy
Let me introduce some of the ones we use.
Resources: copy resources from SRC /main/resources to classpath.
Compile: Compiles the project source code
TestResources: copy SRC /test/resources to the classpath of the test
Test: Runs a unit test
Package: a package
Install: Installs the JAR into the local repository
Deploy: Publish jars to remote or private repositories
Customize operations to a phase in the lifecycle
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>${basedir}/assembly/package.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Copy the code
The different life cycles run together.
mvn clean package
Restrict the Clean life cycle, then execute the Default life cycle through the Package phase.
Use of private servers and mirrors
Configure the mirror
MirrorOf specifies which repository settings.xml configuration mirror to broker
<localRepository>
/Users/zhangpanqin/.m2/repository
</localRepository>
<mirrors>
<mirror>
<id>aliyunmaven</id>
<! Id of the mirrored central repository -->
<mirrorOf>central</mirrorOf>
<name>Central warehouse image</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
Copy the code
You can also configure private servers in pom.xml
<repositories>
<repository>
<id>ali_maven</id>
<url>https://maven.aliyun.com/repository/central/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
Copy the code
Define different configuration environments
You can also start different JDK environments, or different images, depending on your configuration environment
Settings. The XML configuration.
<profiles>
<profile>
<id>test-1</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<repositories>
<repository>
<id>public-snapshots</id>
<name>public-snapshots</name>
<url>http://mvn.uinnova.cn/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<! This element specifies how often updates occur. Maven compares local POM timestamps with remote POM timestamps. The options are: always (always), daily (default, daily), interval: X (where X is a time interval in minutes), or never (never). -->
<updatePolicy>daily</updatePolicy>
<! What to do when Maven validators fail to validate files -ignore, fail, or WARN. -->
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
Copy the code
It can also be configured for a specific project
<profiles>
<! MVN clean package -Pdev -->
<profile>
<id>local</id>
<properties>
<profileActive>local</profileActive>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>dev</id>
<properties>
<profileActive>dev</profileActive>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<profileActive>prod</profileActive>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profileActive>test</profileActive>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
</profiles>
Copy the code
Maven – assembly – the plugin package
Pom. The XML configuration
<build>
<finalName>flyyou</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>${basedir}/assembly/package.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Copy the code
package.xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<! -- id identifier, suffix added to build file name. ${artifactId}-${id}.tar.gz- >
<id>${project.version}-${profileActive}-bin</id>
<! Directory - specifies whether the package contains playing packaging layer (such as finalName terminal - dispatch, the duty is true, all files are placed in bags of terminal - dispatch directory, or directly on top of package root directory) -- -- >
<! -- <includeBaseDirectory>true</includeBaseDirectory>-->
<! Gz (or TGZ), tar.bz2 (or tbz2), jar, dir, war, etc.
<formats>
<format>tar.gz</format>
<format>zip</format>
</formats>
<fileSets>
<! -- jar in target directory, package in lib directory of zip file -->
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<! Zip bin -->
<fileSet>
<directory>${basedir}/bin</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>*.sh</include>
<include>*.bat</include>
</includes>
</fileSet>
<! Package the doc directory in the root directory of the project into the doc directory in zip.
<fileSet>
<directory>${basedir}/doc</directory>
<outputDirectory>doc</outputDirectory>
<includes>
<include>pic/**</include>
<include>*.md</include>
<include>*.pdf</include>
</includes>
</fileSet>
<! Add the configuration files and log configuration files from the compile path classes to the zip file conf -->
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>application-${profileActive}.yml</include>
<include>logback-spring.xml</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Copy the code
Package as shown below
Used with SpringBoot
application.yml
spring:
application:
name: flyyou-service
profiles:
active: @profileActive@
Copy the code
Graphical interface to switch development environment, no need to constantly modify configuration files
*-local.yml is ignored in.gitignore, local development environment does not affect each other.
Use the following command to package the development environment for automatic builds
mvn clean package -Ddev
This article was created by Zhang Panqin on his blog www.mflyyou.cn/. It can be reproduced and quoted freely, but the author must be signed and indicate the source of the article.
If reprinted to wechat official account, please add the author’s official qr code at the end of the article. Wechat official account name: Mflyyou