1 maven的简单介绍
- Maven是Apache下的项目管理工具,它由纯Java语言开发,可以帮助我们更方便的管理和构建Java项目
2 maven的优点
- jar包管理
- 从Maven中央仓库获取标准的规范的jar包以及相关依赖的jar包,避免自己下载到错误的jar包
- 本地仓库统一管理jar包,使jar包与项目分离,减轻项目体积
- maven是跨平台的可以在window、linux上使用
- 清晰的项目结构
- 多工程开发,将模块拆分成若干工程,利于团队协作开发
- 一键构建项目:使用命令可以对项目进行一键构建
3 maven的安装
- maven官网:https://maven.apache.org/
- maven仓库:https://mvnrepository.com/
- 安装步骤
- 安装jdk
- 从官网中下载对应的版本
- 解压安装,然后配置环境变量,需要配置MAVEN_HOME,并且将bin目录添加到Path环境变量中
- 在命令行中输入mvn -v,看到版本信息表示安装成功
4 maven仓库
- maven仓库的分类
- 本地仓库:本地仓库就是开发者本地已经下载下来的或者自己打包所有jar包的依赖仓库,本地仓库路径配置在maven对应的conf/settings.xml配置文件,当再有新的maven项目时,优先从本地仓库取jar包不会重新从互联网下载
- 私有仓库:私有仓库可以理解为自己公司的仓库,也叫Nexus私服。相当于自己公司每天将需要的jar文件放入到一个固定位置,然后配置成该位置就能获取公司开发所需的相关jar包,没外网开发时,就用私有仓库
- 中央仓库:中央仓库即maven默认下载的仓库地址,是maven维护的,官方维护的地址,速度慢,一般不用
- 镜像仓库:由于网络访问的原因,在国内如果需要下载国外jar包的时候会受限,阿里云维护了一个和中央仓库内容完全相同的mvn仓库,我们可以将镜像仓库配置为阿里云的mvn仓库,就可以更加快速地下载jar包
- 仓库优先级:本地仓库>镜像仓库>中央仓库
5 maven常用命令
- clean:清理编译后的target目录
- compile:编译(java),只编译main目录,不编译test中的代码
- test-compile:编译test目录下的代码
- test:运行test中的代码
- package:编译、将项目打成jar包
- install:编译(javac)、将项目打成jar包(jar)、发布项目jar包到本地仓库的GroupId/ArtifactId/Version文件夹中
- deploy:打包后将其安装到pom文件中配置的远程仓库
- site:生成站点目录
- 以上命令可以在terminal中,通过例如
mvn clean
方式执行,也可以在idea的mvn边栏中对应项目下–Lifecycle中点击执行
6 maven配置文件:apache-maven-3.6.3/conf/settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!--1. 配置本地仓库地址-->
<localRepository>/Users/wusihan/javaMvn</localRepository>
<pluginGroups>
</pluginGroups>
<proxies>
</proxies>
<servers>
</servers>
<mirrors>
<!--2. 配置镜像仓库-->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<profiles>
<!--3. 配置jdk:当idea有多个jdk,需要指定maven项目编译和运行的jdk,如果不在settings.xml文件中配置,只是在idea中修改使用的jdk版本,那么每次引入新的pom内容后,jdk版本都会被修改为默认版本-->
<profile>
<!--id不能随便起-->
<id>jdk-1.8</id>
<!--开启JDK的使用-->
<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>
</profiles>
</settings>
7 maven项目
-
maven通过坐标的方式来获取 jar包,坐标由GroupId、ArtifactId、Version组成,可以从互联网,本地等多种仓库源获取jar
- GroupId:类似包名,防止重名,规则一般是域名反转,例如:com.msb
- ArtifactId:一般使用项目名
- Version:版本 1.0-snapshot(快照版),表示是自己用于测试的版本,当真正上线后,改为1.0版本即可
-
maven项目编译后的内容不再放入idea默认的out目录中,而是放入target文件夹中
-
maven将项目看作对象,项目之间有依赖,继承,聚合的关系
-
maven可以创建pom工程、jar工程、war工程,pom工程是逻辑工程,里面不能写代码,一般作为其他工程的父工程或聚合工程,用于对jar包进行版本控制。而jar工程就是最后会被打成jar包的工程,war工程就是最终被打成war包的工程。是具体哪种工程通常在pom文件中通过如下方式指定
<packaging>pom</packaging>
8 项目间关系
8.1 依赖
-
A工程开发或运行需要B工程支持,代表A依赖B,通俗理解就是A中需要B对应的jar包支持
-
maven通过pom文件,来注入项目依赖的其他项目,省去手动添加jar包的操作
-
依赖的传递性:如果项目A依赖mybatis,而项目B只需依赖项目A(pom文件中引入项目A),那么mybatis的jar包,也会自动导入到项目B中
-
依赖原则
- 最短路径优先原则:A–>(依赖)B–>C–>D(1.0),且同时A–>E–>D(2.0),那么根据最短路径原则D(2.0)会被导入项目A,因为A通过E到D的路径最短
- 最先声明原则:A–>B–>C(1.0),A–>D–>C(2.0),此时最短路径无法确认唯一依赖,maven使用最先声明原则,看pom文件中编写的依赖顺序,如果pom文件中A先依赖B,那么就使用C(1.0)
- 但在idea中测试时发现,如果是在同一个pom文件中,A直接依赖B的两个不同版本,会使用下面的B对应的版本
-
排除依赖:A–>B–>C,但如果A只想依赖B自身,也就是只想导入B的jar包,不想同时导入C对应的jar包
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.3</version> <exclusions> <exclusion> <!--正常导入时,会导入log4j-core和log4j-api,此处将lo4j-api排除,那么就只剩下log4j-core--> <!--此处不用再写版本号因为排除肯定是,对应的jar都排除,而不是只排除某个版本的jar--> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> </exclusions> </dependency>
-
依赖范围(scope)
-
compile:scope默认值为compile,编译和运行时都有效
-
provided:典型的例子是servlet-api,编译和测试项目时,需要该依赖,但项目运行时,例如部署到tomcat后,容器tomcat已提供这个jar,就不需要maven重复引入
-
runtime:运行时有效,例如jdbc,编译时根本用不到,但真正打包后必须有,否则无法执行
-
system:与porvided类似,打包后,不重复引入,且编译和测试时,使用的jar,不在本地仓库和远程仓库,而是人为指定操作系统上的一个路径,需要配合systemPath标签一同使用
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.3</version> <scope>system</scope> <systemPath>/Users/wusihan/myjars/hawtio-app-2.10.1.jar</systemPath> </dependency>
-
test:编译和测试时使用,运行时不用,例如junit
-
import:一般作为父工程的pom文件中会有dependencyManagement标签,这个标签中的scope,才能使用import,表示必须使用父工程中规定的依赖版本号,不允许自己修改
-
创建pom工程
<!--表示创建的是pom工程,此处可以填写jar或war,创建不同的工程--> <packaging>pom</packaging> <properties> <banben>2.13.3</banben> </properties> <!--dependencyManagement中的dependencies内的jar包,不会被真正引入项目,只是用于声明管理版本号--> <dependencyManagement> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${banben}</version> </dependency> </dependencies> </dependencyManagement>
-
将该pom工程打成jar包并发布到本地仓库
-
将该pom工程作为新工程的父工程
<?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>org.example</groupId> <artifactId>testMavenChild</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.example</groupId> <artifactId>testmaven</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../testmaven/pom.xml</relativePath> </parent> <dependencies> <dependency> <!--注意此处不必再配置版本号,会直接使用其父工程中的版本号--> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <!--此处如果写版本号,那么会覆盖父工程提供的版本号,但如果父工程中,使用scope为import,那么即使此处提供版本号,子工程也不会使用,而是使用父工程中提供的版本--> </dependency> </dependencies> </project>
-
-
8.2 继承
- 上面两个项目就是继承关系
- 所谓项目的继承,实际就是pom文件的继承
8.3 聚合
- 一个项目下多个模块,例如大学系统,拆分成搜索平台、学习平台、考试平台等
- 在idea中,创建一个maven的project后,在其内部创建maven的module,这样module和之前project之间就是聚合关系,聚合关系和继承关系差不多,都是以pom工程定义版本号,创建module后,project的pom.xml中会自动加入标签,表示其内模块有哪些
9 插件
9.1 编译器插件
-
使用plugins标签,setttings.xml文件中配置的是全局jdk,此处可以对单个项目或聚合项目中的单个模块,配置使用的java编译器版本
<build> <plugins> <plugin> <!--插件坐标--> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <!--源代码使用JDK版本,注意,前提idea必须有这个版本的jdk,否则不生效--> <source>1.7</source> <!--源代码编译为class文件的版本,需要跟上面保持一致--> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
9.2 资源拷贝插件
-
默认情况,只有resources文件夹下内容,会被打包到target的class内,但使用mybatis时,可能有些xml配置文件,不在resources路径下,如果想让这些配置文件也一同打包到target/class内,就需要使用资源拷贝插件
<build> <resources> <resource> <!--配置好后,src/main/java下的*.xml文件也会被打包进target--> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build>
9.3 tomcat插件
-
之前建立的maven项目,必须使用idea将项目和本地某个tomcat关联,然后才能启动
-
可以使用tomcat插件,这样就不用再部署到本地的某个tomcat上了
-
创建maven时,选择create from archetype–maven-archetype-webapp,因为tomcat插件使用前提是当前是一个web项目
-
然后修改pom文件如下
<build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/</path> </configuration> </plugin> </plugins> </build>
-
此时maven边栏–项目–Plugins中,多了一个tomcat7插件,执行其内的tomcat7:run,此时该项目就在tomcat插件上跑起来了