D:\MyMavenguigu\apache-maven-3.8.6\conf
找到conf目录下的setting.xml配置文件进行编辑
找到标签<localRepository>
本标签代表本地仓库
默认仓库目录:Default: ${user.home}/.m2/repository
user.home代表的是用户家目录,C盘->用户->用户名
<!-- 这个目录可以等执行构建命令时,由Maven创建 -->
<localRepository>d:\maven-repo</localRepository>
第一次是本地仓库是没有任何数据的,需要去下载,通过国内阿里云进行下载
本地仓库->镜像->中央仓库
//此处在mirrors里
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirros>
默认1.5,我们修改为1.8
<profiles>
<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>
左边类似于数学中的坐标 y(竖轴)x(横轴)y(纵轴)
使用x、y、z三个向量作为空间的坐标系,可以在空间中唯一的定位到一个点
使用三个向量在Maven的仓库中唯一的定位到一个jar包
举例
d:
cd maven-workspace\spaceVideo//进入到工作空间中
//生成Maven工程
//mvn是主命令 archetype generate是子命令
//一个插件可以有好多个目标
//archetype是我们调用的插件 generate是插件的目标
mvn archetype:generate
运行该mvn archetype:generate命令,会进行下载
过程:
Choose archetype:7快速开始
groupId:com.atguigu.maven
artifactId:pro01-maven-java
version:defualt默认
package:默认
Y:回车/N重新输入
成功
INFO BUILD SUCCESS
pro01-maven-java
src
main
...
test
...
pom.xml//本工程的配置文件
将version改为4.12
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>//将version改为4.12
<scope>test</scope>
</dependency>
</dependencies>
pom.xml自动生成
此处只修改了version版本为4.12
<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.0modelVersion>
<groupId>com.atguigu.mavengroupId>
<artifactId>pro01-maven-javaartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>jarpackaging>
<name>pro01-maven-javaname>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
project>
pom.xml和web.xml大同小异
①含义
POM:Project Object Model,项目对象模型。和POM相似的是:DOM(Document Object Model),文档对象模型。它们都是模型思想的具体体现
②模型化思想
POM表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。这样我们就可以用程序来管理项目了。我们在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数据作为一个对象,这样就可以在程序中计算与现实事物相关的数据。
③对应的配置文件
POM理念集中在Maven工程根目录下pom.xml这个配置文件中。所以这个pom.xml配置文件就是Maven工程的核心配置文件。其实学习Maven就是学习这个文件怎么配置,各个配置有什么用。
超级POM是所有POM的父POM和Java的Object大同小异
有效POM是最后的结果
想自动化完成,该目录就非常重要
从src/main/java和test/java下找到源代码
编辑结果放在target/class…目录下
而测试就在main方法的目录下
测试代码:
package com.atguigu.maven;
import org.junit.Test;
import com.atguigu.maven.Calculator;
//静态导入的效果是将Assert类中的静态资源导入当前类
import static org.junit.Assert.*;
public class CalculatorTest{
@Test
public void testSum(){
//1.创建Calculator对象
Calculator calculator = new Calculator();
//2.调用Calculator对象的方法,获取到程序运行实际的结果
int actualResult = calculator.sum(5,3);
//3.声明一个变量,表示程序运行期待的结果
int expectedResult = 8;
//4.使用断言来判断实际结果和期待结果是否一致
//如果一致:测试通过,不会抛出异常
//如果不一致:抛出异常,测试失败
assertEquals(expectedResult,actualResult);
}
}
类:
package com.atguigu.maven;
public class Calculator{
public int sum(int i,int j){
return i+j;
}
}
运行Maven中的构建相关的命令时,必须进入到pom.xml所在的目录。如果没有在pom.xml所在的目录运行Maven的构造命令,那么将看到下面的错误信息
The goal you specified requires a project to execute but there is no
POM in this directory
mvn -v 命令和构建无关,只要正确配置了PATH,在任何目录下都可以执行。而构建相关的命令要在pom.xml所在目录下运行–操作哪个工程,就进入这个工程的pom.xml目录。
mvn clean
效果:删除target目录
第一次工作会下载相关文件
主程序编译:mvn compile
测试程序编译:mvn test-compile
主体程序编译结果存放的目录:target/classes
测试编译程序结果存放的目录:target/test-classes
mvn test
测试的报告存放的目录:target/surefire-reports
mvn package
第一次执行也需要下载Jar包
Building jar
BUILD SUCCESS
构建一个Jar放到了target目录下的…位置
\pro01-maven-java-1.0-SNAPSHOT.jar
pro01-maven-java是我们的artifactId配置值
-1.0…Version是我们的版本号配置值
默认artifactId+version拼接
打包时测试成功才会去编译
所以会经过
Resources: 资源处理
Compile:编译
testCompile->testResourcescompile->compile->resources
测试程序编译,测试资源处理,主体程序编译,主体程序资源处理
上面的操作由Maven的生命周期控制
在产生的Jar包里只有主体程序的class文件没有测试类的class文件
mvn compile
第一次执行会下载一些东西,最后INFO然后显示下面的成功语句
BUILD SUCCESS
会自动生成一个target目录
该目录下保存了构建结果,打开classes发现类的class文件
如果要编译测试类
mvn test-compile
测试第一次执行也要下载东西
出现BUILD SUCCESS后进入到test-classes里可以看到测试类的class编译文件
如果执行clean 也要下载插件
看到BUILD SUCCESS后表示执行成功,target文件被删除
调用mvn test直接主程序+测试程序全部编译target
执行mvn test第一次执行下载Jar包
如果特意将程序改为不等于8的结果:
int actualResult = calculator.sum(2,3);
直接 再次 mvntest
看到BUILD FAILURE 表示构建失败
Failed to execute goal//失败的执行目标
maven.plugins:maven-surefire-plugin:test执行失败
There are test failures.
Tests run: 1, Failures: 1
java.lang.AssertionError: expected:<8> but was:<5>
在target下会有一个surefire-reports目录
该文件夹会存放测试报告
如果没有出错则是命令行的截取
mvn install
我们使用
mvn clean install
这样的好处是确保是最新的编译
[INFO] Installing D:\maven-workspace\spaceVideo\pro01-maven-java\target\pro01-maven-java-1.0-SNAPSHOT.
这个Jar包在我们的工程目录下面 target
com\atguigu\maven\pro01-maven-java\1.0-SNAPSHOT\pro01-maven-java-1.0-SNAPSHOT.jar
这个路径对应了我们配置文件
com\atguigu\maven对应groupId标签
pro01-maven-java对应artifactId标签
版本号对应version标签
Jar名字是artifactId+version标签拼接的名称
第二行INFO
[INFO] Installing D:\maven-workspace\spaceVideo\pro01-maven-java\pom.xml to d:\maven-repo\com\atguigu\maven\pro01-maven-java\1.0-SNAPSHOT\pro01-maven-java-1.0-SNAPSHOT.pom
这个到仓库的pom文件和我们写的一模一样
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4
groupId:com.atguigu.maven
artifactId:pro02-maven-web
其他默认
打开该工程的pom文件,修改为4.12
index.jsp
<html>
<body>
<h2>Hello World!</h2>
<a href="helloServlet">Access Servlet</a>
</body>
</html>
servlet类
package com.atguigu.maven;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.*;
public class HelloServlet extends HttpServlet{
protected void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
response.getWriter().write("hello maven web");
}
}
web.xml
DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<servlet>
<servlet-name>helloServletservlet-name>
<servlet-class>com.atguigu.maven.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloServletservlet-name>
<url-pattern>/helloServleturl-pattern>
servlet-mapping>
web-app>
我们使用网站查询serlvet依赖的配置信息
https://mvnrepository.com
https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api/3.1.0
<!-- 为了能够正常使用HttpServlet,需要导入servlet-api依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
打包war包
mvn clean package
我们将打包的war包解压部署到Tomcat的webapps文件下
D:\MyTomcat\apache-tomcat-8.0.42\webapps
手动启动Tomcat
首先找到Tomcat文件路径
使用cmd进入到Tomcat中
cd D:\MyTomcat\apache-tomcat-8.0.42
cd bin
startup.bat
此时已经启动了服务器
我们打开浏览器输入
http://localhost:8080/demo/index.jsp
点击Access Servlet超链接,给服务器发送请求
让TomCat调用我们的doGet方法
明确一个意识:从来只有Web工程依赖Java工程,没有反过来Java工程依赖Web工程。本质上来说,Web工程依赖的Java工程其实就是Web工程里导入的jar包,最终Java工程会变成Jar包,放在Web工程的WEB-INFO/lib目录下。
web工程变成war包 Java工程则编程了war包里依赖的jar包
war包含jar
在pro02-maven-web工程的pom.xml中,找到dependencies(依赖)标签,在依赖标签中做如下配置:
<dependencies>
<groupId>com.atguigu.mavengroupId>
<artifactId>pro01-maven-javaartifactId>
<version>1.0-SNAPSHOTversion>
dependencies>
在web工程的src下新建一个test目录进行测试
并且将pro01-maven-java的计算器测试类赋值到新建的test目录下的com.atguigu.maven/
直接
mvn test
只要运行成功看到了BUILD SUCCESS就说明
web工程通过pom的dependencies成功依赖到了Java工程
通过mavn package来查看war包里的WEB-INFO/lib下是否有jar包
D:\maven-workspace\spaceVideo\pro02-maven-web\target\pro02-maven-web-1.0-SNAPSHOT.war
The following files have been resolved:
[INFO] javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
[INFO] junit:junit:jar:4.12:test
[INFO] org.hamcrest:hamcrest-core:jar:1.3:test
我们通过 mvn dependency:tree查看详细
也就是说,是junit测试类引用的该类依赖
配置依赖范围所使用的标签是:scope
标签的位置:dependencies/dependency/scope
标签可选值:compile/test/provided/system/runtime/import
main目录下的Java类:HelloServlet->pro02-maven-web
Compile范围引入的依赖:pro01-maven-java
pro01maven-java中的类:Calculator
依赖关系显示
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- 通过指定依赖工程的坐标完成依赖 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro01-maven-java</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
依赖测试
我们通过import的方式来测试是否可以依赖到
import com.atguigu.maven.Calculator;
public class HelloServlet extends HttpServlet{
compile的范围成功了,此处是跨越了2个工程的调用
主体程序调用测试程序的类成功
如果是test,则不能调用,相当于Junit这个类的范围只能让测试目录调用
test范围在打包时是不会生成jar包的,因为junit的辅助性质的,打包部署到服务器也没有什么实质的意义,只会增加服务器负担
provided翻译意思为已提供,比如Tomcat,Tomcat中是有Servlet这个jar包的,所以在部署的时候既然服务器已经提供了jar包就不需要再将依赖jar包部署到服务器中,这样容易引起Jar包冲突
结论
①概念
A依赖B,B依赖C,那么A在没有配置对C的依赖的情况下,A里能不能直接使用C?
②传递的原则
在A依赖B,B依赖C的前提下,C能否能够传递到A,取决于B依赖C时使用的范围。
我们通过spring-core的Jar包依赖来测试传递性,此处范围为compile
让pro01-maven-java下的pom.xml里的dependencies中增加一个单数形式的依赖标签
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>4.0.0.RELEASEversion>
dependency>
使用mvn dependency:tree来查看依赖关系
如果D依赖了A,那么C可以使用D吗?
由于本地仓库的代码并不是最新的,所以需要重新安装一下
在命令行pro01-maven-java路径下使用mvn clean install
D可以通过A依赖配置去引用到C依赖,前提是compile范围
当A依赖B,B依赖C而且C可以传递到A的时候,A不想要C,需要在A里把C排除掉。而往往这种情况都是为了避免jar包之间的冲突
<dependency>
<groupId>com.atguigu.mavengroupId>
<artifactId>pro01-maven-javaartifactId>
<version>1.0-SHAPSHOTversion>
<scope>scope>
<exclusions>
<exclusion>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
exclusion>
exclusions>
dependency>
配置完毕后,再次执行mvn dependency:list
现在可以看到,再次查询依赖列表时,commons不再其中
Maven工程之间,A工程继承B工程
本质上A工程的pom.xml中配置继承了B工程pom.xml的配置
在父工程中统一管理项目中依赖信息,具体来说是管理依赖信息的版本
创建父工程和前面创建pro01-maven-java一样
工程名pro03-maven-parent
工程创建好之后,要修改它的打包方式:
<groupId>com.atguigu.mavengroupId>
<artifactId>pro03-maven-parentartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
只有打包方式为pom的Maven工程能够管理其他Maven工程。打包方式为pom的Maven工程中不写业务代码,它专门管理其他Maven工程的工程
使用指令 mvn archetype:generate
快速访问直接回车
groupId:com.atguigu.maven
工程名artifactId:pro03-maven-parent
其他直接回车
将pro03-maven-parent的pom文件中的打包方式
packaing改为 pom
并且可以删除依赖标签(配置)
模块工程类似于IDEA中module,所以需要进入pro03-maven-parent工程的根目录,然后运行mvn archetype:generate命令来创建模块工程
mvn archetype:generate
自动聚合
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.atguigu.mavengroupId>
<artifactId>pro03-maven-parentartifactId>
<version>1.0-SNAPSHOTversion>
parent>
<groupId>com.atguigu.mavengroupId>
<-- 省略groupId和version后,子工程自己的坐标只保留artifactId -->
<artifactId>pro04-maven-moduleartifactId>
<version>1.0-SNAPSHOTversion>
<name>pro04-maven-modulename>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
dependencies>
project>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>4.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>4.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>4.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>4.0.0.RELEASEversion>
dependency>
dependencies>
dependencyManagement>
如果想修改版本
直接在父类配置文件该version就行了,子类默认遵循父类配置
借助properties标签来创建我们自定义属性标签
标签名:属性名
标签值:属性值
引用方式:${atguigu.spring.version}
<atguigu.spring.version>${atguigu.spring.version}atguigu.spring.version>