尚硅谷 Maven
1.目前的技术在开发中存在的问题
问题①一个项目就是一个工程
如果项目非常庞大,就不适合继续使用package来划分模块,最好是每一个模块对应一个工程,利于分工协作。
解决方案:借助于Maven就可以将一个项目拆分成多个工程。
问题②项目中需要的jar包必须手动“复制”、“粘贴”到WEB-INF/lib目录下
带来的问题是:同样的jar包文件重复出现在不同的项目工程中,一方面浪费存储空间,另外也让工程比较臃肿。
解决方案:借助Maven,可以将jar包仅仅保存在“仓库”中,有需要使用的工程“引用”这个文件接口,并不需要真的把jar包复制过来。
问题③jar包需要别人替我们准备好,或到官网下载
不同技术的官网提供jar包下载的形式是五花八门的
有些技术就是通过Maven和SVN提供下载的
如果是以不正规的方式下载的jar包,那么其中的内容很可能也是不规范的。
解决方案:借助于maven可以以一种规范的方式下载jar包,因为所有知名的框架和第三方工具jar包以及按照统一的规范存在了Maven的中央仓库中。以规范的方式下载jar包,内容是可靠的。
问题④一个jar包依赖的其他jar包需要自己手动加入到项目中
如果所有jar的依赖都需要程序员自己非常清楚的了解,那么就会极大的增加学习成本。
解决方案:Maven会自动将依赖的jar包导入进来。
2.Maven是什么
①Maven是一款服务于java的自动化构建工具
②构建
概念:以“Java源文件”、“框架配置文件”、“JSP”、“HTML”、“图片”等资源为“原材料”去“生产”一个可运行的项目的过程。
编译=》部署=》搭建
编译:JAVA源文件=》编译成Class字节码文件=》交给JVM执行
部署:一个BS项目最终运行的并不是动态Web工程本身,而是这个动态Web工程“编译的结果”
3.构建过程中的各个环节
①清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
②编译:将java源程序编译成class字节码文件
③测试:自动化测试,自动调用junit程序
④报告:测试程序执行的结果
⑤打包:动态web工程打war包,java工程打Jar包
⑥安装:Maven特定的概念,将打包得到的文件复制到“仓库”中的指定位置
⑦部署:将动态web工程生成的war包复制到Servlet容器的指定目录下,使其可以运行
4.安装Maven核心程序
①检查JAVE_HOME环境变量
C:\Users\Dell>echo %JAVA_HOME% C:\Program Files\Java\jdk-12.0.1 |
②解压Maven核心程序压缩包,放在一个非中文为空格路径下
③配置Maven相关的环境变量
1.MAVEN_HOME或M2_HOME
E:\devinstall\apache-maven-3.6.3
2.添加path
%M2_HOME%\bin
3.cmd下输入命令
C:\Users\Dell>MVN -v Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: E:\devinstall\apache-maven-3.6.3\bin\.. Java version: 12.0.1, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-12.0.1 Default locale: zh_CN, platform encoding: GBK OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows" |
5.Maven的核心概念
①约定的目录结构
${basedir} |-- pom.xml |-- src | |-- main | | -- java || com.xxx.xxx 项目源码 | | `-- resources || 项目配置文件 .xml等 | | `-- filters | | `-- test | | `-- java | | `-- resources | | `-- filters |
②POM
③坐标
④依赖
⑤仓库
⑥生命周期/插件/目标
⑦继承
⑧聚合
6.第一个Maven工程
①创建约定的目录结构
1.根目录:工程名
2.src目录:源码
3.pom.xml文件:Maven工程的核心配置文件
4.main目录:存放主程序
5.test目录:存放测试程序
6.java目录:存放java源文件
7.resource目录:存放框架或者其他工具的配置文件
②为什么要遵守约定的目录结构呢?
1.Maven要负责我们这个项目的自动化构建,以编译为例,Maven要想自动进行编译,那么它必须知道JAVA源文件保存在哪里。
2.如果我们自定义的东西想要让框架或者工具知道,有两种办法:①以配置的方式明确告诉框架;②遵守框架的内部约定
3.约定大于配置,配置大于编码
7.常用Maven命令
①注意:执行与构建过程相关的Maven命令,必须进入pom.xml所在的目录。
mvn clean:清理
mvn compile:编译主程序
mvn test-compile:编译测试程序
mvn test:执行测试
mvn package:打包
mvn install:安装
mvn site:生成站点
8.关于联网问题
1.Maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须由特定的插件来完成,而插件本身并不包含在Maven的核心程序中。
2.当我们执行Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查找。
3.本地仓库的默认位置:系统中当前用户的家目录\.m2\repository
4.Maven核心程序如果在本地仓库中找不到需要的插件,name它会自动连接外网到中央仓库下载
5.如果无法连接外网,则构建失败
6.修改默认本地仓库的位置,可以让Maven核心程序到我们事先准备好的目录下查找插件
1.找到Maven解压目录的配置文件settings.xml
E:\devinstall\apache-maven-3.6.3\conf\settings.xml文件中
<localRepository>/path/to/local/repo</localRepository> |
将localRepository标签包裹的内容改为本地准备好的插件目录。
9.POM
①含义:Project Object Model项目对象模型
②pom.xml对于Maven工程是核心配置文件,与构建过程相关的一切配置都在这个文件中进行配置,重要程度相当于web.xml对于动态web工程
10.坐标
使用下面三个向量在仓库中唯一定位一个Maven工程
①groupid 公司或者组织域名倒序+项目名
<groupid>com.atguigu.maven</groupid> |
②artifactid 模块名
<artifactid>hello</artifactid> |
③version 版本
<version>1.0.0</version> |
11.仓库
①本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务
②远程仓库1.私服;搭建在局域网环境中,为局域网范围内的所有Maven工程服务;2.中央仓库:假设在internet上,为全世界所有Maven工程服务;3.中央仓库镜像:为了分担中央仓库的流量,提升用户访问速度
仓库中保存的内容:Maven工程
Maven自身所需要的插件
第三方框架或工具的jar包
我们自己开发的Maven工程
12.依赖
①Maven解析依赖信息时,会到本地仓库中查找被依赖的jar包,对于我们自己开发的jar包,我们需要执行mvn install命令安装后,就可以进入仓库。
②依赖的范围
1.compile范围依赖
对主程序是否有效:有效
对测试程序是否有效:有效
是否参与打包:参与
是否参与部署:参与
2.test范围依赖
对主程序是否有效:无效
对测试程序是否有效:有效
是否参与打包:不参与
是否参与部署:不参与
典型例子 junit
3.provided范围依赖
对主程序是否有效:有效
对测试程序是否有效:有效
是否参与打包:不参与
是否参与部署:不参与
典型例子
servelet-api.jar包需要别人替我们准备好,或到官网下载
13.生命周期
①各个构建环节执行的顺序:不能打乱顺序,必须按照既定的正确顺序来执行。
②Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的。
③Maven的核心程序为了更好的实现自动化构建,按照这样的特点执行生命周期中的各个阶段:不论现在要执行生命周期中哪一个阶段,都是从这个生命周期最初的位置开始执行的。
14.Eclipse中使用Maven
①Maven插件:Eclipse内置
②Maven插件的设置windows=》preferences
1.installations:指定Maven核心程序的位置,不建议使用插件自带的Maven程序,而应该使用我们自己解压的那个
2.user settings:指定conf/settings.xml的位置,进而获取本地仓库的位置
②基本操作
勾选create a simple project
设置通过Maven创建工程的JDK版本
setting.xml文件中的profiles中的profile标签。
pom.xml配置文件
<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>com.wuxinzhe.maven</groupId> <artifactId>MavenProject</artifactId> <version>0.0.1-SNAPSHOT</version> </project> |
如果中央仓库慢,可以修改成阿里云的镜像
<mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/repositories/central</url> </mirror> |
15.在Eclipse中执行Maven命令
选中pom.xml=》右键=》run as=》Maven build=》Goals框中输入compile=》run
报错:Maven [ERROR] 不再支持源选项 5。请使用 6 或更高版本
在pom.xml中,project标签内配置以下内容
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>12</maven.compiler.source> <maven.compiler.target>12</maven.compiler.target> </properties> |
16.Eclipse内创建Maven Web工程
和之前创建Java工程一样,唯一区别Packaging中选择war创建,但是创建的Web工程缺少WEB-INF和META-INF目录。以下为解决步骤:
选择项目=》右键properties=》Project Facets=》Dynamic Web Module(取消选中=》apply=》然后再选中)=》apply=》点击Further configuration available=》在content directory输入框输入src/main/webapp=》点击ok
The superclass “javax.servlet.http.HttpServlet” was not found on the Java Build Path
在pom.xml加入依赖
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> </dependencies> |
17.依赖的传递性
①好处:可以传递的依赖不必再每个模块工程中都重复声明,在“最下面”的工程中依赖一次即可
②注意:非compile范围的依赖,不能传递,所以在各个工程模块中,如果有需要就得重复声明依赖。
18.依赖的排除,依赖中添加如下标签排除
<exclusions> <exclusion> <groupId></groupId> <artifactId></artifactId> </exclusion> </exclusions> |
19.依赖的原则
20.统一依赖设置版本号
<properties> <javax.servlet-version>2.5</javax.servlet-version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>${javax.servlet-version}</version> <scope>provided</scope> </dependency> </dependencies> |
21.继承
①现状
Hello依赖的junit:4.0
HelloFriend依赖的junit:4.0
MakeFriends依赖的junit:4.9
由于test范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致。
②需求:统一管理各个模块工程中对junit依赖的版本。。。
③解决思路:将junit依赖统一提取到“父”工程中,在子工程中声明junit依赖时不指定版本,以父工程中统一设定的为准。
④操作步骤
1.创建一个Maven工程为父工程。注意:打包的方式pom
<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>com.wuxinzhe.maven</groupId> <artifactId>ParentMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> </project> |
2.在子工程中,声明对父工程的引用
<parent> <groupId>com.wuxinzhe.maven</groupId> <artifactId>ParentMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 以当前文件为基准的父工程pom.xml文件的相对路径 --> <relativePath>../ParentMaven/pom.xml</relativePath> </parent> |
3.将子工程的坐标中与父工程坐标中重复的内容删除
<groupId>com.wuxinzhe.maven</groupId> <version>0.0.1-SNAPSHOT</version> |
4.在父工程中统一junit的依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.0</version> <scope>test</scope> </dependency> |
5.在子工程中删除junit依赖的版本号部分
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> |
父工程ParentMaven配置文件完整内容
<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>com.wuxinzhe.maven</groupId> <artifactId>ParentMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.0</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> </project> |
子工程ChildMaven配置文件完整内容
<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> <artifactId>ChildMaven</artifactId> <parent> <groupId>com.wuxinzhe.maven</groupId> <artifactId>ParentMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 以当前文件为基准的父工程pom.xml文件的相对路径 --> <relativePath>../ParentMaven/pom.xml</relativePath> </parent> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> </project> |
22.聚合
①作用:一键安装各个模块工程
②配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块
<!-- 在父工程pom.xml配置聚合 --> <modules> <!-- 指定各个子工程的相对路径 --> <module>../ChildMaven</module> </modules> |
③使用方式:
在聚合工程右键pom.xml——>run as ——> run install
idea设置默认maven配置, 避免每次设置maven
https://blog.csdn.net/ladymorgana/article/details/87887109
21/05/25 换机器重新搭建一个springboot项目
运行项目报错①
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for com.hscode-web:hscode:0.0.1-SNAPSHOT: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.2.5.RELEASE from/to central (https://repo.maven.apache.org/maven2): transfer failed for https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.5.RELEASE/spring-boot-starter-parent-2.2.5.RELEASE.pom and ‘parent.relativePath’ points at no local POM @ line 5, column 10
[ERROR] Non-resolvable parent POM for com.hscode-web:hscode:0.0.1-SNAPSHOT: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.2.5.RELEASE from/to central (https://repo.maven.apache.org/maven2): transfer failed for https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.5.RELEASE/spring-boot-starter-parent-2.2.5.RELEASE.pom and ‘parent.relativePath’ points at no local POM @ line 5, column 10: Connection reset -> [Help 2]
[ERROR]
解决方案
修改E:\install\apache-maven-3.6.0\conf\setting.xml文件,mirrors内添加maven阿里云镜像节点:
<mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> |
右侧maven 执行clean,然后install,就可以下载依赖了
运行项目报错②
Unable to import maven project: See logs for details。当前idea版本为2018.3.1 maven版本3.8.1,看网上说idea版本和某些版本的maven不兼容
解决方案
把maven版本降为3.6.0,就可以正常导入包了。
运行项目报错③
Exception in thread “main” java.lang.ClassNotFoundException: com.hscodeweb.hscode.HscodeApplication
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:375)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:107)
解决方案
project structure修改项目jdk降低为jdk1.8
运行项目报错④
springboot错误: 找不到或无法加载主类springboot错误: 找不到或无法加载主类
解决方案
将项目目录中除src和pom.xml的其余文件全部删除掉,然后重新用idea打开,application.yml的图标也正常了,就可以启动了。
运行项目报错④
maven package 打包的时候报错
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project hscode: Unable to generate classpath: org.apache.maven.artifact.resolver.ArtifactResolutionException: Unable to get dependency information for org.apache.maven.surefire:surefire-junit-platform:jar:2.22.2: Failed to retrieve POM for org.apache.maven.surefire:surefire-junit-platform:jar:2.22.2: Could not transfer artifact org.apache.maven.surefire:surefire-junit-platform:pom:2.22.2 from/to nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public): java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
[ERROR] org.apache.maven.surefire:surefire-junit-platform:jar:2.22.2
[ERROR]
[ERROR] from the specified remote repositories:
[ERROR] nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public, releases=true, snapshots=false)
[ERROR] Path to dependency:
[ERROR] 1) dummy:dummy:jar:1.0
项目目录中执行 mvn clean package -Dmaven.test.skip=true 可以成功打包