Maven is a tool for managing and building Java projects.
It simplifies dependency management (jar files) to avoid version conflicts, provides a standard project structure, and offers a cross-platform automated build process.
Installation
Download it from the
official website
and unzip it. Configure the local repository by modifying the <localRepository> tag in conf/setting.xml to a specific directory.
| |
To configure the Aliyun mirror, modify the <mirror> tag in conf/setting.xml by adding a child tag:
| |
Configure environment variables: set MAVEN_HOME to the Maven installation directory and add its bin folder to the PATH variable.
Verify the installation: run mvn -v in the command line to check the output.
Dependency Configuration
Dependencies are the jar files required to run the project. A single project can include multiple dependencies.
Configuration steps:
- Add the
<dependencies>tag inpom.xml. - Use the
<dependency>tag inside<dependencies>to import coordinates. - Define the
groupId,artifactId, andversion. - Refresh the configuration to import the new dependencies.
| |
You can find dependency coordinates at https://mvnrepository.com/ .
Dependency Transitivity
Dependencies are transitive.
- Direct Dependency: A dependency explicitly defined in the current project.
- Indirect Dependency: When a dependency depends on other resources, the current project implicitly depends on those resources.
When you add a dependency that relies on other packages, those packages are added automatically.
If you don’t need a specific sub-dependency, you can exclude it (this breaks the dependency link; no version is required for excluded resources).
| |
Dependency Scope
By default, jar files are available everywhere. You can use <scope>...</scope> to limit their scope:
- Main program scope (inside the
mainfolder). - Test program scope (inside the
testfolder). - Packaging and execution (during the
packagephase).
| Scope Value | Main Program | Test Program | Packaging (Runtime) | Example |
|---|---|---|---|---|
| compile (def) | Y | Y | Y | log4j |
| test | - | Y | - | junit |
| provided | Y | Y | - | servlet-api |
| runtime | - | Y | Y | jdbc driver |
| |
Lifecycle
The Maven lifecycle abstracts and unifies the build process for all Maven projects.
There are 3 independent lifecycles:
- clean: Cleanup tasks.
- default: Core tasks like compile, test, package, install, and deploy.
- site: Generating reports and publishing sites.
Each lifecycle consists of several phases. Phases are sequential; later phases depend on the completion of earlier ones.
clean
- pre-clean
- clean: Removes files generated by previous builds (the
targetfolder). - post-clean
default
- validate
- initialize
- generate-sources
- process-sources
- generate-resources
- process-resources
- compile: Compiles the source code.
- process-classes
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources
- test-compile
- process-test-classes
- test: Runs tests using a unit testing framework (e.g., JUnit).
- prepare-package
- package: Packages compiled code (e.g., jar, war).
- verify
- install: Installs the project into the local repository.
- deploy
site
- pre-site
- site
- post-site
- site-deploy
Within the same lifecycle, running a later phase automatically triggers all preceding phases.
Multi-module Design
Multi-module design allows splitting a large project into several independent modules during the design phase. If one module needs functionality from another, it can simply depend on that module.
Common entities or utility classes can be placed in separate modules to be shared. This improves project management, maintenance, scalability, and resource sharing.
Inheritance
Dependencies like Lombok might be used in every module. Instead of declaring it in every module, you can use inheritance.
Inheritance Relationship
Create a parent project and move shared dependencies to its configuration. Child projects inheriting from the parent will automatically inherit these dependencies, eliminating redundant configuration.
Inheritance describes the relationship between two projects, similar to inheritance in Java. It simplifies dependency management and ensures consistency.
| |
In JavaWeb development, the parent project can inherit from spring-boot-starter-parent, while other modules inherit from that parent project.
Usually, child projects are located in subdirectories of the parent project.
Example:
- Parent project packaging type is
pom:
| |
Maven Packaging Types:
- jar: Standard module packaging. SpringBoot projects usually use this (run via embedded Tomcat).
- war: Standard web program packaging for external Tomcat servers.
- pom: Parent or aggregation project. Contains no code, used only for dependency management.
- Child project specifies the parent:
| |
- Parent project configures shared dependencies:
| |
Version Management
If only some modules need a dependency, you can manage the version in the parent project to ensure consistency.
Use the <dependencyManagement> tag for version locking.
Parent Project:
| |
Child Project:
| |
The
<dependencyManagement>in the parent only manages the version; it does not actually import the dependency into children. Children must explicitly include the dependency (without a version) to use it.In contrast,
<dependencies>imports the dependency into all child projects automatically.
Attribute Configuration (Properties)
You can use custom properties to centralize version management in the parent project.
Define attributes:
| |
Reference attributes:
| |
Centralized management in the parent project:
| |
To update a version, you only need to change the property value in the parent project.
Aggregation
If one module depends on another, you usually have to install the dependency module to the local repo before packaging the main module. This gets tedious with many modules.
Maven aggregation allows for one-click project builds (clean, compile, test, package, install, etc.).
- Aggregation: Organizing multiple modules into a single unit for simultaneous building.
- Aggregation Project: An “empty” project containing only a
pom.xml(usually the same as the parent project in inheritance). - Purpose: Fast project building without manually following dependency order.
Define sub-modules in the aggregation project using the <modules> tag.
| |
Running compile, package, or install on the aggregation project will automatically sync those operations to all sub-modules.
| Feature | Inheritance | Aggregation |
|---|---|---|
| Purpose | Simplifies dependency config and management. | Enables rapid project building. |
| Similarities | Packaging is pom; usually combined in the same file. | Design-oriented modules with no actual source code. |
| Differences | Relationship defined in child modules. Parent doesn’t “know” children. | Relationship defined in the aggregator. Aggregator “knows” children. |
Private Repositories
A private repository (Nexus, Artifactory) is a remote repository hosted on a local network. It acts as a proxy for the central repository and facilitates resource sharing and synchronization within a team.
When a project needs a dependency, Maven checks the local repo. If missing, it checks the private repo. If the private repo doesn’t have it, it downloads it from the central repository, caches it, and serves it to the local repo.
Companies usually provide a private repository, so you won’t need to configure your own.
Private Repo Types and Project Versions
Private Repo Categories:
- RELEASE: For finished RELEASE versions of internal code.
- SNAPSHOT: For internal development SNAPSHOT versions.
- Central: Proxied dependencies downloaded from the Maven Central Repository.
Project Versioning:
- RELEASE: Stable, finished versions for deployment, stored in the RELEASE repo.
- SNAPSHOT: Unstable, work-in-progress versions, stored in the SNAPSHOT repo.
Configuration
Set the private repo username and password in conf/settings.xml under the <servers> tag:
| |
Configure the download address in settings.xml using the <mirrors> and <profiles> tags:
| |
Configure the upload target in the parent project’s pom.xml:
| |
Once configured, execute the deploy lifecycle phase on the parent project to publish it to the private repository.