目录
maven简介:
- maven声明周期和间接:
-
阶段 处理 描述 验证 validate 验证项目 验证项目是否正确且所有必须信息是可用的 编译 compile 执行编译 源代码编译在此阶段完成 测试 Test 测试 使用适当的单元测试框架(例如JUnit)运行测试。 包装 package 打包 创建JAR/WAR包如在 pom.xml 中定义提及的包 检查 verify 检查 对集成测试的结果进行检查,以保证质量达标 安装 install 安装 安装打包的项目到本地仓库,以供其他项目使用 部署 deploy 部署 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程
- maven不仅仅是构建工具,还是依赖管理工具,项目信息管理工具
- 提供免费中央仓库,自动下载构建,衍生出私有仓库例如:Nexus
- 通过坐标的方式引入第三方的开源类库,统一对开源的依赖. 私有仓库可以对自己的类库进行管理
- mven可以帮助管理分散在项目中的项目信息,项目描述,开发者列表,版本控制系统地址,许可证,缺陷管理系统地址等.通过maven可以自动生成站点,插件,可以轻松的获得项目文档,测试报告,静态分析报告,源码版本日志报告,等非常具有价值的项目信息.
- 统一依赖管理,统一的版本管理,减少学习成本. 统一生命周期管理,提高开发效率.统一项目信息管理等
- maven
- 其他构建工具:Make,Ant,Gradle
- Maven和Gradle优缺点:
- TODO
-
-
maven安装和配置
- 安装
- maven目录结构
-
2019/11/07 12:32 <DIR> bin 2019/11/07 12:32 <DIR> boot 2019/11/07 12:32 <DIR> conf 2019/11/07 12:32 <DIR> lib 2019/11/07 12:32 17,504 LICENSE 2019/11/07 12:32 5,141 NOTICE 2019/11/07 12:32 2,612 README.txt
- bin:(存放mvn运行的脚本)
-
2019/11/07 12:32 228 m2.conf #存放classworlds配置文件(后边详解) 2019/11/07 12:32 5,741 mvn # 2019/11/07 12:32 6,349 mvn.cmd #cmd结尾的win下运行的 2019/11/07 12:32 1,485 mvnDebug #断点调试指令 2019/11/07 12:32 1,668 mvnDebug.cmd # 2019/11/07 12:32 1,532 mvnyjp #? TODO
-
-
boot:(类加载)
-
2019/11/07 12:32 52,873 plexus-classworlds-2.6.0.jar #类加载器框架,maven使用该框架加载自己的类库, 2019/11/07 12:32 11,560 plexus-classworlds.license #授权文件
-
-
conf:(配置文件)
-
E:\Program Files\apache-maven-3.6.3\conf>dir /S/B /A:A E:\Program Files\apache-maven-3.6.3\conf\settings.xml #主要的全局配置文件 E:\Program Files\apache-maven-3.6.3\conf\toolchains.xml #通过该文件实现指定多个jdk版本,当然也可以通过插件方式配置 E:\Program Files\apache-maven-3.6.3\conf\logging\simplelogger.properties #日志配置文件
-
-
lib:(包含所有maven运行的java类库)
-
2019/11/07 12:32 <DIR> ext 2019/11/07 12:32 <DIR> jansi-native 2019/11/07 12:32 501,879 commons-lang3-3.8.1.jar #依赖的jar包 2019/11/07 12:32 11,560 commons-lang3.license #软件许可 .....
-
-
LICENSE:(maven使用的软件许可)
-
NOTICE:(记录maven包含的第三方软件)
-
README.txt:(MAVEN的简要介绍,安装需要,和如何安装的简要指令)
-
- maven目录结构
- 配置
- 配置代理
-
<proxies> <!-- proxy | Specification for one proxy, to be used in connecting to the network. |--> <proxy> <id>optional</id> <active>true</active> <!-- 是否激活该代理 --> <protocol>http</protocol> <!-- 协议信息 --> <username>proxyuser</username> <password>proxypass</password> <host>proxy.host.net</host> <port>80</port> <nonProxyHosts>local.net|some.host.com</nonProxyHosts> <!-- 指定哪些主机名不需要代理,支持通配符--> </proxy> </proxies>
-
-
优化配置
-
设置MAVEN的OPTS环境变量: -Xms128m -Xmx512m.java默认的最大可用内存可能满足不了maven,有时候会出现栈溢出的情况,尽量修改用户环境变量中的配置来修改maven,不要修改maven下的文件,maven如果升级又会恢复初始值.
-
配置用户范围的setting.xml,升级后就不会有任何影响
-
尽量不要使用IDE内嵌的Maven,用工具配合命令就会出现构建不一致的问题.最好使用保持一致(尤其是在多模块开发的时候)
-
- 配置代理
- 安装
-
Maven使用入门
-
maven插件的配置
- 如果有代码中有main方法,jar包生成不会自动生成可执行的jar包,MANIFEST.MF文件不会有main方法的类类信息.
-
<!-- 生成可执行jar插件 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.demo.Test001</mainClass> <!--指定启动的main方法位置--> </transformer> </transformers> <createDependencyReducedPom>false</createDependencyReducedPom> <!--禁止在编译的target目录下生成配置文件,不影响使用--> </configuration> </execution> </executions> </plugin> </plugins> </build>
-
对比一下执行jar包和不可执行jar包之间文件目录的区别
-
-
- 说明:
- simple-test-1.0-SNAPSHOT.jar: 可以执行的jar,带main信息的
- original-simple-test-1.0-SNAPSHOT.jar: 原始的jar包
- 通过java -jar simple-test-1.0-SNAPSHOT.jar就可以启动jar包了
- simple-test-1.0-SNAPSHOT.jar: 可以执行的jar,带main信息的
-
- 如果有代码中有main方法,jar包生成不会自动生成可执行的jar包,MANIFEST.MF文件不会有main方法的类类信息.
- 使用ArcherType生成项目骨架:
- mvn archetype:generate
- 选择骨架,添加坐标,版本号,生成骨架
-
-
Maven实战案例(以后具体演示)
- 通过一个具体的需求构建maven的模块划分.
-
坐标和依赖
-
<groupId>com.consola.org</groupId> <!--通常与域名反向对应,当前项目隶属的实际项目--> <artifactId>hello-world</artifactId> <!--使用实际项目名作为前缀,方便从一个lib文件夹中找到某个项目的一组构件.默认的项目名+版本的+.jar,可以进行指定配置后边详解--> <version>1.0-SNAPSHOT</version> <!--版本规范,后边详解其功能和作用--> <packaging>jar</packaging> <!--打包方式:jar,war, 默认:jar--> <!--classifier:没有改标签后边再补.54页-->
- 完成account-email模块构建
- 依赖范围:
-
<!-- 三种类路径:编译,测试,运行 compile:默认使用,对于编译,测试,运行,三种都有效; test:测试依赖范围,只对测试的类路径下有效,只在编译测试代码或者运行测试代码是有效. provided:编译时有效,运行时无效; runtime:运行时依赖来; system:系统依赖范围.依赖于三种类路径关系,不是通过maven仓库解析的,是和系统绑定的. import:改以来不会对三种类路径产生实际的影响. -->
-
- 传递性依赖:
- 依赖的调用
- 依赖关系:
- A->B->C->X(1.0) 和 A->D->X(2.0): 出现两个版本的依赖路径最近这优先
- A->B->X(1.0) 和 A->D->X(2.0): 依赖长度一样,按照pom申明的顺序,第一申明优先.
- 依赖关系:
- 可选依赖:
-
<!--optional:表示可选依赖,不是很常用,了解--> <!--两个数据库驱动包,只能选一个--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> <optional>true</optional> </dependency> <dependency> <groupId>com.hynnet</groupId> <artifactId>oracle-driver-ojdbc6</artifactId> <version>12.1.0.1</version> <optional>true</optional> </dependency> <!--另一个项目的pom中做显示的声明,--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency>
-
- 最佳实践:
- 排除依赖
- A->B->X(1.0): X依赖的版本不在中央仓库,导致缺少包运行,这时候另一个项目中有一个对应的实现.可以通过exclusions标签显式的声明那个项目的实现.
- A->B->X(1.0) 和 A->X(1.0),不会出现groupId和artifactId相同,version版本不同的依赖
- 归类依赖
-
<properties> <!-- 通过改标签统一的对版本进行控制 --> <!-- spring --> <spring-cloud.version>Edgware.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies>
-
- 优化依赖
- 查看当前项目的已解析依赖
- mvn dependency:list
- 查看项目的依赖树:
- mvn dependency:tree
- 查看依赖的使用:
- mvn dependency:analyze
- 两种情况:
- Used undeclared dependencies found(使用没有声明的依赖),删除有潜在的风险,这种依赖是通过直接依赖传递进来的,升级直接依赖的时候,相关传递性依赖的版本有可能发生变化,这种变化不易察觉,可能会导致项目出错.最好显式的声明依赖
- Unused declared dependencies found(没使用声明的依赖),查看依赖只会查看到编译主代码和测试代码需要的依赖,一些执行,测试需要的依赖发现不了,可以通过该方法找到一些没用的依赖,但不完全.
- 查看当前项目的已解析依赖
- 排除依赖
-
-
仓库
- maven文件路径:
- 仓库地址+包路径+版本号:文件下就是存放包的位置
- 仓库分为:
- 远程仓库:
- 中央仓库
- 私有仓库:
- 节省带宽,加速构建,部署第三方构建,提高稳定性,增强控制.(管理员可以通过私有仓库进行权限的控制)降低中央仓库的符合
-
<repositories> <repository> <!--可以声明多个远程仓库--> <id>rdc-releases</id> <!--id必须唯,重复将会覆盖一--> <name>wuse</name> <url>https://repo.rdc.aliyun.com/repository/129186-release-u560yC/</url> <!--仓库地址--> <releases> <enabled>true</enabled> <!--开启仓库的发布版本下载支持--> </releases> <snapshots> <enabled>false</enabled> <!--关闭远程仓库的快照版本的下载支持--> <updatePolicy>daily</updatePolicy> <checksumPolicy>ignore</checksumPolicy> </snapshots> <!-- 对于releases和snapshots有两个子标签: updatePolicy:远程仓库检查更新的频率never-从不检查更新;always-每次构建都检查;interval-每隔几分钟检查一次; daily-默认一天检查一次 checksumPolicy:检查检验和文件的策略.当构建被部署到maven仓库中时,会同时部署对应的效验和文件.warn-默认,在执行构建的时候输出警告信息;fail-原道效验和错误就让构建失败;ignore-完全忽略效验和错误. --> <layout>default</layout> <!--仓库的布局,默认是maven3,可以是maven1或者maven2--> </repository> </repositories>
- 其他公共仓库
- 本地仓库:
- 可以通过pom文件配置仓库的地址
- 远程仓库:
- 远程仓库的认证:
-
<server> <id>rdc-releases</id> <!-- 给配置的id和pom文件的远程仓库的id,或者是setting文件中的远程仓库的id必须一致. ---> <username>Hg0KGQ</username> <password>k0AN1teUip</password> </server>
- 仓库信息可以配置在pom文件中,认证信息必须配置在setting.xml文件中,配置在本机比较安全.
-
- 部署到远程仓库
-
<!-- 配置构建部署地址 --> <distributionManagement> <repository> <!--发布版本的构建仓库--> <id>rdc-releases</id> <url>https://repo.rdc.aliyun.com/repository/129186-release-u560yC/</url> </repository> <snapshotRepository> <!--快照版本的仓库--> <id>rdc-snapshots</id> <url>https://repo.rdc.aliyun.com/repository/129186-snapshot-Kwk5Qv/</url> </snapshotRepository> </distributionManagement>
-
- 快照版本
- **-alpha-*,1.0,表示稳定的发布版本,而**-SNAPSHOT-**,1.0.20090122,表示不稳定的快照版本
- 正式上线后的模块不会存在比较大的改动,快照版和稳定版分开利于管理和分类
- 从仓库解析依赖的机制
- 先从本地仓库找,如果没有依赖的构建去远程仓库下载;
- 当依赖的范围是system(也就是java的一些内部包)时候,maven直接从文件系统解析构建
- 根据依赖的坐标找相应的构建,解析,没有遍历所有的远程仓库,下载,解析
- 如果依赖的版本是TELEASE或者LATEST,则基于更新策略读取所有远程仓库的元数据F:\maven\Repository\cn\ztuo\bitrade\cloud\maven-metadata-local.xml,将其与本地仓库的对应元数据合并后,计算出RELEASE或者LATEST真实的值,然后基于这个真实的值检查本地和远程仓库.
-
<!-- 元信息代码,列举出了所有存在该构件的所有可用版本, --> <?xml version="1.0" encoding="UTF-8"?> <metadata> <groupId>cn.ztuo.bitrade</groupId> <artifactId>cloud</artifactId> <versioning> <latest>1.4.2-SNAPSHOT</latest> <!-- 最新的版本 --> <release>1.0</release> <!-- 最新的发布版本 --> <versions> <version>1.0</version> </versions> <lastUpdated>20210107040112</lastUpdated> </versioning> </metadata> <!-- 注意:在依赖声明中使用LATEST和TELEASE是不推荐的做法,因为maven随时都可能解析到不同的构件,可能今天是LATEST是1.3.6,明天就成为1.4.0-SNAPSHOT了,且maven不会告诉用户,这样的变化.当这种变化造成构件失败的时候,发现问题会变得比较困难,.maven3不再支持此种方法,当依赖的版本是快照版本,maven也需要检查更新,和上边的步骤是一样的 最后注意: 仓库元数据并不是永远正确的,有时候当用户发现无法解析某些构建,或者解析得到错误构建的时候,就有可能是出现了仓库元数据错误,这时就需要手工,或者使用工具对其进行修复 -->
-
- 如果依赖版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据****.xml,然后对比合并,得到最新的快照版本,然后基于值检查本地仓库或者,从远程仓库下载.
- 如果构建的版本是时间戳格式的快照,则复制其时间戳格式的文件至非时间戳格式的快照,并使用该非时间戳格式的构建.
- 当依赖的版本不明晰的时候,入RELEASE,LATEST和SNAPSHOT,maven需要基于<releases>和<snapshots>,只有仓库开启了对于发布版本的支持时,才能访问该仓库的发布版本构建信息,对于快照版本也是同理;
- 其次要注意的是<updatePolicy>,该元素配置了检查更新的频率通过命令的方式加入参数-U,可以进行强制更新,忽略配置文件
- 当maven检查完更新策略,并决定检查依赖更新的时候,就需要检查仓库 元数据maven-metadata.xml计算出来
- 先从本地仓库找,如果没有依赖的构建去远程仓库下载;
-
镜像
-
<mirror> <id>repo3</id> <mirrorOf>central</mirrorOf> <!-- 可以使用通配符: *:匹配所有远程仓库;或者是:external:* == 匹配素有远程仓库; repo1和repo2:用逗号隔开,多个远程仓库; *,!repo1:匹配所有的repo1除外 --> <name>Human Readable Name for this Mirror.</name> <url>https://mvnrepository.com/</url> </mirror>
-
- 仓库搜索服务
-
#常用的搜索网站 1,https://repository.sonatype.org/ 2,https://mvnrepository.com/ 3,https://mvnbrowser.com/ 4,https://lanars.com/
-
- maven文件路径:
maven提供的模板:
1:appfuse-basic-jsf (创建一个基于Hibernate,Spring和JSF的Web应用程序的原型)
2: appfuse-basic-spring(创建一个基于Hibernate,Spring和Spring MVC的Web应用程序的原型)
3: appfuse-basic-struts(创建一个基于Hibernate,Spring和Struts 2的Web应用程序的原型)
4: appfuse-basic-tapestry(创建一个基于Hibernate,Spring 和 Tapestry 4的Web应用程序的原型)
5: appfuse-core(创建一个基于Hibernate,Spring 和 XFire的jar应用程序的原型)
6: appfuse-modular-jsf(创建一个基于Hibernate,Spring和JSF的模块化应用原型)
7: appfuse-modular-spring(创建一个基于Hibernate, Spring 和 Spring MVC 的模块化应用原型)
8: appfuse-modular-struts(创建一个基于Hibernate, Spring 和 Struts 2 的模块化应用原型)
9: appfuse-modular-tapestry (创建一个基于 Hibernate, Spring 和 Tapestry 4 的模块化应用原型)
10: maven-archetype-j2ee-simple(一个简单的J2EE的Java应用程序)
11: maven-archetype-marmalade-mojo(一个Maven的 插件开发项目 using marmalade)
12: maven-archetype-mojo(一个Maven的Java插件开发项目)
13: maven-archetype-portlet(一个简单的portlet应用程序)
14: maven-archetype-profiles()
15:maven-archetype-quickstart()
16: maven-archetype-site-simple(简单的网站生成项目)
17: maven-archetype-site(更复杂的网站项目)
18:maven-archetype-webapp(一个简单的Java Web应用程序)
19: jini-service-archetype(Archetype for Jini service project creation)
20: softeu-archetype-seam(JSF+Facelets+Seam Archetype)
21: softeu-archetype-seam-simple(JSF+Facelets+Seam (无残留) 原型)
22: softeu-archetype-jsf(JSF+Facelets 原型)
23: jpa-maven-archetype(JPA 应用程序)
24: spring-osgi-bundle-archetype(Spring-OSGi 原型)
25: confluence-plugin-archetype(Atlassian 聚合插件原型)
26: jira-plugin-archetype(Atlassian JIRA 插件原型)
27: maven-archetype-har(Hibernate 存档)
28: maven-archetype-sar(JBoss 服务存档)
29: wicket-archetype-quickstart(一个简单的Apache Wicket的项目)
30: scala-archetype-simple(一个简单的scala的项目)
31: lift-archetype-blank(一个 blank/empty liftweb 项目)
32: lift-archetype-basic(基本(liftweb)项目)
33: cocoon-22-archetype-block-plain([http://cocoapacorg2/maven-plugins/])
34: cocoon-22-archetype-block([http://cocoapacorg2/maven-plugins/])
35:cocoon-22-archetype-webapp([http://cocoapacorg2/maven-plugins/])
36: myfaces-archetype-helloworld(使用MyFaces的一个简单的原型)
37: myfaces-archetype-helloworld-facelets(一个使用MyFaces和Facelets的简单原型)
38: myfaces-archetype-trinidad(一个使用MyFaces和Trinidad的简单原型)
39: myfaces-archetype-jsfcomponents(一种使用MyFaces创建定制JSF组件的简单的原型)
40: gmaven-archetype-basic(Groovy的基本原型)
41: gmaven-archetype-mojo(Groovy mojo 原型)