Maven
的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM
)
如图蓝色部分为 Maven
,其不包括外部其他部分,上部分为核心,下部分为各种插件。Maven
的作用如下
src
、resource
、target
等统一项目结构Maven
是由 Java
语言编写的,同样采用了面向对象的思想
Maven
官网进行下载 maven.apache.org/maven目录/conf/settings.xml
配置文件,配置阿里镜像地址(配置到 <mirrors>
标签里)【可选】配置环境变量:新建 MAVEN_HOME:Maven根目录
,修改Path添加 %MAVEN_HOME%\bin
(注意:Maven
依赖环境变量中有 JAVA_HOME
),CMD输入 mvn -v
验证
【可选】因为Java默认的最大可用内存往往不够满足Maven运行需要,比如较大的项目时,使用Maven生成项目站点需要占用大量内存,可选配置 MAVEN_OPTS:-Xms128m -Xmx512m
注意 Maven
是由 Java
研发的,所以 Maven
依赖 Java
仓库概念
:仓库用于存储资源(各种 Jar
包),其分为本地仓库、远程仓库、中央仓库
Maven
私服,部门/公司范围内储存资源的仓库Maven
团队维护的,维护所有资源的仓库坐标概念
:坐标用于描述仓库中资源的位置,其构成部分及说明如下:
gourpId`:组织名,定义该 `Maven` 项目隶属组织,常是域名反写,如 `org.example.demo
artifactId
:项目名,定义该 Maven
项目名称
version
:版本号,定义该 Maven
项目的版本号
packaging
:定义项目的打包方式,如成果物类型 war
或 jar
,如组织项目的 pom
类型
Jar
包的获取会逐级搜索,如本地仓存在则直接使用本地仓,如不存在则到远程仓获取。以此类推
命令 | 说明 |
---|---|
mvn archetype:generate | 创建 Maven 项目,可通过参数指定坐标等 可以使用骨架:常用7号 quickstart 普通项目,10号 webappWEB 项目 |
mvn clean | 把已经编译好的项目的所有信息清除(target 文件夹) |
mvn compile | 自动导入 POM 中的依赖,并把核心代码部分编译后,放置在 target 目录下 |
mvn test | 通过此命令可以执行 test 文件夹下的测试用的内容,实现项目测试(同时执行了 compile ) |
mvn package | 将 Maven 项目进行打包,放置在 target 目录下(同时执行了 test ) |
mvn install | 将刚刚项目打完的包安装到本地仓库,由 maven 进行管理(同时执行了 package ) |
mvn deploy | 项目发布,将 maven 本地库中管理的资源发布到远程库中 |
<!--当前项目的maven资源坐标-->
<groupId>org.example</groupId>
<artifactId>MVNDemo01</artifactId>
<version>1.0-SNAPSHOT</version>
<!--此项目在mvn package的过程中,要打成什么样的包,通常是jar或war,也可能是pom-->
<packaging>jar</packaging>
<!-- 项目相关信息 -->
<name>MVNDemo01</name>
<description>xxx</description>
<url>http://maven.apache.org</url>
<!-- 参数配置 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 依赖管理 -->
<dependencies>
<dependency>
</dependency>
</dependencies>
<!-- 依赖版本管理 -->
<dependencyManagement>
</dependencyManagement>
<!-- 项目构建 -->
<build>
<plugins>
<plugin>
</plugin>
</plugins>
</build>
依赖是可以传递的,很有可能会发生依赖传递冲突问题,其优先级如下:
POM
文件中声明时,后配置的覆盖先配置的处理依赖传递有如下两种标签:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springboot</artifactId>
<version>1.1</version>
<!-- 可选依赖(默认false,可传递) -->
<optional>true</optional>
<!-- 排除依赖 -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>bbb</artifactId>
</exclusion>
</exclusions>
</dependency>
依赖范围: 可以通过 <scope>
标签指定其依赖范围,其作用如下:
scope | 编译 | 测试 | 打包 | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | Y | junit(仅测试使用) | ||
provided | Y | Y | 不传递 | servlet-api(Tomcat中包含) |
runtime | Y | jdbc(可防止编写时意外导入) | ||
system | Y | Y | 插件配置 includeSystemScope | 依赖来自本地系统,需要配合标签 systemPath 使用 |
import | 引入依赖项目,配合 <type>pom</type> 使用 |
依赖范围具有传递性,开发时根据实际情况使用
插件的使用可以通过官网查询,不同插件有不同使用方式,根据文档说明进行操作。如下简单示例源码插件配置
xml复制代码<build>
<plugins>
<!-- 使用具体插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<!-- 配置执行条件/位置:具体使用参考插件文档 -->
<executions>
<execution>
<!-- 操作目标,如下为主代码及test代码 -->
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
<!-- 插件执行阶段(生命周期哪个阶段) -->
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
聚合用于快速构建 Maven
工程,一次性构建多个项目/模块。如多个项目/模块依赖,执行命令时需要每一个工程都进行编译,打包,安装,测试,部署等生命周期的命令,一个一个去执行这些命令效率非常低
Maven
提供了聚合的配置,实现统一执行命令,实现方法:创建一个无代码聚合工程,并在 POM
中配置所有聚合的项目/模块
xml复制代码<!-- 打包类型为聚合 -->
<packaging>pom</packaging>
<!-- 配置模块名称 -->
<modules>
<!-- 标签内部值为子模组pom.xml所在路径 -->
<!-- 表示与自己同级的child1项目目录 -->
<module>../child1</module>
<!-- 表示为自己目录下child2项目目录 -->
<module>child2</module>
</modules>
只是聚合项目关心有什么模块,模块不需要知道被谁聚合了
Maven
项目提供继承的特性,可以利用继承实现所有项目资源版本统一的问题。其继承的父类资源包括:
继承项 | 说明 |
---|---|
groupId version | 项目相关的内容。可以重写,默认父类的值 |
properties | 父级工程在 properties 标签中定义的变量,子工程使用 ${} 使用 |
dependencies | 相当于强制继承,子工程中一定被导入父工程该标签内的 Jar 包 |
dependencyManagement | 常用的一种统一资源的继承方式,只会继承版本而不会强制让子工程依赖资源 子工程通过在 dependency 内添加 groupId 和 artifactId 即可,当然也可以重写 version 版本号 |
build pluginManagement | 如上的一种统一资源的继承方式,其使用如上,不仅继承版本号,还会继承声明的使用方式 |
继承的实现需要子项目声明父项目,注意 Maven
是单继承,其声明方式如下:
xml复制代码<!-- 定义工程的父工程 -->
<parent>
<groupId>org.example.parent</groupId>
<artifactId>demo-parent</artifactId>
<version>1.0.0.RELEASE</version>
<!-- 填写父工程的POM位置,省略不写视为在父工程内/父工程为远程项目,仓库获取 -->
<relativePath>../parent/pom.xml</relativePath>
</parent>
只是子项目声明了父项目是谁,父项目不需要知道被谁继承了
Maven
提供属性管理,其管理方式属性类型有:自定义属性、内置属性、Setting属性、Java系统属性、环境变量属性
xml复制代码<!-- 定义自定义属性 -->
<properties>
<mybatis-plus.version>3.1.2</mybatis-plus.version>
<druid.version>1.1.17</druid.version>
</properties>
<!-- 使用自定义属性 -->
<version>${druid.version}</version>
<!-- 内置属性:含 ${basedir} ${version} 等 -->
<!-- Setting属性:配置文件 setting.xml 中的标签属性,属于动态属性,如 ${settings.localRepository} 等 -->
<!-- Java系统属性、环境变量属性:通过命令 mvn help:system 可以获取到属性 -->
Maven
提供资源加载属性值功能,其为项目内的其他资源文件使用定义的自定义属性,调用方式相同 ${}
使用如下
xml复制代码<!-- 定义哪个文件夹下文件开启POM属性过滤功能,检测到 ${} 就替换属性 -->
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtreing>true<filtering>
</resource>
</resources>
</build>
版本管理含
RELEASE
和SNAPSHOT
,正式版、快照版
Maven
可以进行多环境配置参数,通过打包命令添加参数完成,可了解一下
【Nexus
】为常用私服,安装及使用绕道参考
更改编译 Java
源码的 jdk
版本
xml复制代码<!-- 通过更改项目的 pom.xml,添加 java 编译插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<!-- 或者在 properties 设置 jdk 版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
更改 Maven
默认的 JDK
版本,更改 Maven
目录下的 conf/settings.xml
文件,以后建立的项目源码编译都是指定的 jdk
版本
xml复制代码<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
xml复制代码<!-- Spring项目打包插件:可能和 appassembler-maven-plugin 不兼容 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 测试插件:不写进行默认测试,这里配置了该插件跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<!-- 应用不部署到远程仓库中 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
Appassembler
打包有三种核心打包方式,其中常用打包为可执行程序和守护服务方式。如下介绍最为常用的守护方式,该方式可生成资源后直接在服务器中运行为服务
Appassembler
打包方式的优点:
wrapper
方式进行管理,直接运行 bin/
下的可执行文件 start | stop | console | restart
lib
依赖,其打包方式不会将所有依赖打包到一个可执行文件中,分包管理,方便更改部分 jar
包代码,进行部分更新conf/
文件夹下的资源/配置文件,当找不到时才找 jar
包内资源jar
包覆盖到 lib/
下conf/
xxx restart
重启服务xml复制代码<!-- 使用说明: -->
<!-- 1. 修改对应的项目名称 -->
<!-- 2. 修改属性值,输出文件夹目录 -->
<!-- 3. 修改启动类,如下 mainClass 标签 -->
<!-- 配置项目名称及属性,后期配置使用 -->
<name>demo</name>
<properties>
<appassembler.out.name>appassembler-out</appassembler.out.name>
</properties>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.1.0</version>
<!-- 配置插件启动时机 -->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>generate-daemons</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 打包后生成的目录位置及各目录 -->
<target>${project.build.directory}/${appassembler.out.name}</target>
<binFolder>bin</binFolder>
<logsDirectory>logs</logsDirectory>
<repositoryName>lib</repositoryName>
<!-- 为系统配置文件指定一个目录 -->
<configurationDirectory>conf</configurationDirectory>
<!-- 源代码中对应的系统配置文件的位置 -->
<configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
<!-- 是否将配置文件包含到classpath -->
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<!-- 是否拷贝源代码中配置文件中的目录 -->
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<!-- 依赖的lib包的目录格式,flat表示不分目录平铺到lib目录下 -->
<repositoryLayout>flat</repositoryLayout>
<daemons>
<daemon>
<!-- 基本信息配置:名称及启动类 -->
<id>${project.name}</id>
<mainClass>org.example.Starter</mainClass>
<!-- JVM配置设置 -->
<jvmSettings>
<maxStackSize>128</maxStackSize>
<extraArguments>
<extraArgument>-server</extraArgument>
<extraArgument>-XX:+AggressiveOpts</extraArgument>
<extraArgument>-Xmx1G</extraArgument>
<extraArgument>-XX:+HeapDumpOnOutOfMemoryError</extraArgument>
</extraArguments>
</jvmSettings>
<!-- 打包平台配置 -->
<platforms>
<platform>jsw</platform>
</platforms>
<generatorConfigurations>
<generatorConfiguration>
<generator>jsw</generator>
<includes>
<!-- include>linux-x86-32</include -->
<!-- include>linux-ppc-64</include -->
<include>linux-x86-64</include>
<include>windows-x86-64</include>
</includes>
<configuration>
<!-- 手动添加一个系统启动时依赖的第一个classpath,这里通常写为配置文件的目录名,如果不配置,配置文件无法找到 -->
<property>
<name>configuration.directory.in.classpath.first</name>
<value>conf</value>
</property>
<!-- 依赖jar包位置 -->
<property>
<name>set.default.REPO_DIR</name>
<value>lib</value>
</property>
<!-- 日志文件位置 -->
<property>
<name>wrapper.logfile</name>
<value>logs/wrapper-${project.name}.log</value>
</property>
<!-- 日志文件格式:MB兆的方式格式 -->
<property>
<name>wrapper.logfile.format</name>
<value>M</value>
</property>
<!-- 日志文件最大值:10MB -->
<property>
<name>wrapper.logfile.maxsize</name>
<value>10m</value>
</property>
<!-- 日志文件最大分割值:5 -->
<property>
<name>wrapper.logfile.maxfiles</name>
<value>5</value>
</property>
<!-- 配置Windows服务:效果未检测 -->
<property>
<name>wrapper.ntservice.interactive</name>
<value>true</value>
</property>
</configuration>
</generatorConfiguration>
</generatorConfigurations>
</daemon>
</daemons>
</configuration>
</plugin>
该插件可能与
Spring Boot
打包插件冲突,如出现找不到主类清单错误,可选择注释掉Spring Boot
打包插件(spring-boot-maven-plugin
)
Assembly
打包是 Maven
提供的一种打包方式,可以输出自定义的包类型。如上输出守护服务的资源后,可以再通过该插件进行打包输出
xml复制代码<!-- 集合打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<!-- 只执行一次 -->
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 描述文件所在位置 -->
<descriptors>
<descriptor>src/main/assembly/assembly-linux.xml</descriptor>
<descriptor>src/main/assembly/assembly-win.xml</descriptor>
</descriptors>
</configuration>
</plugin>
描述文件用于描述输出文件,如下输出两个压缩文件(文件内容来自上个插件的输出结果)
xml复制代码<!-- src/main/assembly/assembly-linux.xml -->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>linux</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/bin</directory>
<outputDirectory>${project.name}/bin</outputDirectory>
<fileMode>0755</fileMode>
<includes>
<include>${project.name}</include>
<include>wrapper-linux*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/lib</directory>
<outputDirectory>${project.name}/lib</outputDirectory>
<includes>
<include>*.jar</include>
<include>libwrapper-linux*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/conf</directory>
<outputDirectory>${project.name}/conf</outputDirectory>
<includes>
<include>*.yml</include>
<include>banner.txt</include>
<include>wrapper.conf</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/logs</directory>
<outputDirectory>${project.name}/logs</outputDirectory>
<excludes>
<exclude>**/*</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
xml复制代码<!-- src/main/assembly/assembly-win.xml -->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>win</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/bin</directory>
<outputDirectory>${project.name}/bin</outputDirectory>
<fileMode>0755</fileMode>
<includes>
<include>${project.name}</include>
<include>wrapper-windows*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/lib</directory>
<outputDirectory>${project.name}/lib</outputDirectory>
<includes>
<include>*.jar</include>
<include>libwrapper-windows*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/conf</directory>
<outputDirectory>${project.name}/conf</outputDirectory>
<includes>
<include>*.yml</include>
<include>banner.txt</include>
<include>wrapper.conf</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${appassembler.out.name}/jsw/${project.name}/logs</directory>
<outputDirectory>${project.name}/logs</outputDirectory>
<excludes>
<exclude>**/*</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
Maven
项目默认资源在 src/main/resources
目录下,如果资源不在此目录下,需要添加 maven-resources-plugin
插件,并在 resource
中配置资源路径
xml复制代码<!-- 资源打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<!-- 配合 resources 插件添加资源目录 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 打开变量替换声明 -->
<!-- filtering>true</filtering -->
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
下面介绍的是 tomcat7
插件在 pom.xml
文件中的配置,端口默认是 8080
,path
默认是项目名称(可以在 configuration
标签内进行修改)。执行命令 mvn tomact7:run
运行
xml复制代码<!-- 构建 -->
<build>
<plugins>
<!-- 添加tomcat服务器插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- 配置tomcat端口 -->
<port>8080</port>
<!-- Web应用的访问路径
<path>HelloWorld</path>
-->
<!-- 配置tomcat编码,解决GET乱码 -->
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</build>
</plugins>
Maven
本地仓库同步的时候会产生很多不存在的 Jar
包下载准备文件,可以通过该命令行脚本进行清理,保存到 .bat
文件中,在 windows
双击使用
bash复制代码set REPOSITORY_PATH=E:\MavenRepo
rem 正在搜索...
for /f "delims=" %%i in ('dir /b /s "%REPOSITORY_PATH%\*lastUpdated*"') do (
del /s /q %%i
)
rem 搜索完毕
pause