一、maven基础
1、默认的中央仓库地址
- 在${MAVEN_HOME}\maven-model-builder-3.5.3.jar\org\apache\maven\model中的pom-4.0.0.xml文件中
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<!--指定了默认的中央仓库地址-->
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!--指定了默认的插件中央仓库地址-->
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
</project>
- 通过在本地仓库的setting.xml文件中配置<mirror>标签,可以将maven默认的远程仓库地址映射为我们指定的地址,比如映射成阿里云的远程仓库,加快访问速度
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<!--mirrorOf必须要和repository_id一致,映射才会生效-->
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
2、常用maven命令
- mvn clean :删除target目录
- mvn compile:编译main目录下的代码,生成target目录
- mvn test:编译test目录下的文件,在target目录下,生成test-classes文件
- mvn package:将当前的项目打成jar包
- mvn install:将当前项目上传到本地仓库
- mvn deploy:将本地仓库的项目部署到指定服务器
重要:mvn命令是和maven插件绑定的,maven命令是通过插件来执行的
3、maven依赖管理
-
依赖传递
- 依赖具有传递性
- 直接依赖
- 间接依赖:A依赖B,B依赖C,则A间接依赖C
-
依赖传递冲突问题
- 路径优先:当依赖中出现相同的资源时,依赖的层级越深,优先级越低;层级越浅,优先级越高
- 声明优先:当资源在相同层级被依赖时,配置顺序越靠前,优先级越高
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的
-
可选依赖(不透明)
- 对外隐藏当前项目所依赖的资源
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!--optional为true时,当A项目依赖了此项目,就无法看到此项目依赖了junit--> <optional>true</optional> </dependency>
-
排除依赖(不需要)
- 主动排除依赖的资源
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!--optional为true时,当A项目依赖了此项目,就无法看到此项目依赖了junit--> <optional>true</optional> <exclusions> <eclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </eclusion> </exclusions> </dependency>
-
依赖范围
- 依赖的jar默认情况下可以在任何地方使用,可以通过scope标签指定作用范围
- 作用范围
- 主程序范围内有效(main文件范围内)
- 测试程序范围有效(test文件范围内)
- 是否参与打包(package指令范围内有效)
scope 主代码 测试代码 打包 范例 compile(默认) Y Y Y log4j test Y junit provided Y Y servlet-api runtime Y jdbc
4、声明周期与插件
maven对项目构建的声明周期分为3部分
- clean:清理工作
- pre-clean
- clean
- post-clean
- default:核心工作,编译、测试编译、测试、打包、部署等
- site:产生报告,发布站点等
- pre-site
- site
- post-site
- site-deploy
插件
插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能
- 默认maven在各个声明周期上绑定有预设的功能
- 通过插件可以自定义其他功能(可以参考maven官方插件)
- maven-source-plugin:从当前项目构建一个jar包
<!---maven主要的功能是依赖管理和项目构建-->
<!--dependency标签是依赖管理,build标签是项目构建-->
<!--项目构建-->
<build>
<plugins>
<!--把源码打成jar包的插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<!--执行阶段,testCompile后执行-->
<phase>test-compile</phase>
<!--执行操作-->
<goals>
<!--test文件下的源码打成jar包-->
<goal>test-jar</goal>
<!--main文件下的源码打成jar包-->
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
-
maven-shade-plugin:从当前项目构建一个jar包,包含依赖项(生成的jar包,可以通过java -jar命令运行)
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.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>HelloWorld</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
二、maven高级
1、分模块开发与设计
- 将ssm的每一层拆成一个模块
- ssm_entity
- ssm_dao
- ssm_service
- ssm_controller
2、聚合
-
作用:聚合用于快速构建maven项目,一次性构建多个项目/模块
-
制作方式:
- 创建一个空模块,打包类型定义为pom
<packaging>pom</packaging>
- 定义当前模块进行构建操作时关联的其他模块名称
<modules> <module>../ssm_entity</module> <module>../ssm_dao</module> <module>../ssm_service</module> <module>../ssm_controller</module> </modules>
-
注意事项:参与聚合操作的模块最终执行顺序与模块间的依赖有关,与配置顺序无关
3、继承
-
多模块之间jar包依赖冲突,由父项目统一管理依赖
-
作用:通过继承,可以实现在子工程中沿用父工程的配置
-
maven中的继承与java类似,在子工程中配置继承关系
-
制作方式
- 在子工程中的pom.xml文件中,声明其父工程坐标与对应的位置
<parent> <groupId>org.example</groupId> <artifactId>ssm</artifactId> <version>1.0-SNAPSHOT</version> <!--父工程pom文件的相对位置--> <relativePath>../ssm/pom.xml</relativePath> </parent>
- 在父工程中的pom.xml文件中,配置depenencyManagement和pluginManagement
<packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.13.RELEASE</version> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> </plugins> </pluginManagement> </build>
- 在子工程中定义依赖关系,无序声明依赖版本,版本参照父工程中依赖的版本
<dependencyManagement> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> </plugin> </plugins> </build>
-
继承的好处:可以统一配置管理多个模块的依赖版本,防止依赖版本冲突,同时可以减少工作量
4、聚合与继承比较
- 作用
- 聚合:用于快速构建项目
- 继承:用于快速配置
- 相同点
- 聚合与继承的pom.xml文件的打包方式均为pom,两种关系可以并存
- 聚合与继承均属于设计型模块,没有实际的模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
5、属性
- 自定义属性:等同于自定义变量,版本统一的重要性
<!--定义自定义属性-->
<properties>
<spring.version>5.2.13.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<!--使用自定义属性-->
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<!--使用自定义属性-->
<version>${spring.version}</version>
</dependency>
</dependencies>
- 内置属性:使用maven内置属性,快速配置
${basedir}
<!--pom文件中,本项目的version-->
${version}
- Setting属性:使用maven配置文件setting.xml中的标签属性,属于动态配置
<!--setting.xml中配置的本地仓库-->
${settings.localRepository}
- Java系统属性:读取java系统属性
<!--当前用户的家目录-->
${user.home}
- 环境变量属性
<!--env+环境变量名-->
${env.JAVA_HOME}
系统属性和环境变量查询方式: mvn help:system
6、版本管理
-
工程版本
- SNAPSHOT(快照版本、临时版本)
- RELEASE(发布版本、稳定版本)
-
工程版本号约定
-
<主版本>.<次版本>.<增量版本>.<里程碑版本>
-
主版本:表示项目重大架构的变更,如:spring5相对spring4 的迭代
-
次版本:表示有较大的功能增加和变化,或者全面系统的修复漏洞
-
增量版本:表示有重大漏洞的修复
-
里程碑版本:表明一个版本的里程碑
-
7、多环境配置
配置多个环境:开发环境、生产环境
- 配置pom.xml文件,指定多个环境
<profiles>
<!--正式环境-->
<profile>
<id>prod</id>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
<!--将正式环境指定为默认环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--开发环境-->
<profile>
<id>dev</id>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
</dependencies>
</profile>
</profiles>
- 使用maven命令构建项目时指定使用哪个环境,不指定的话,会使用activeByDefault为true的环境
// -P指定使用的profile_id
mvn install -P dev
8、跳过测试
- 通过maven命令跳过测试
mvn package -D skipTests
- 在IDEA中设置跳过测试
- 在pom文件中配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
三、搭建私服
1、Nexus安装、启动与配置
- Nexus下载地址:https://help.sonatype.com/repomanager3/product-information/download
- Nexus启动命令
nexus /run nexus
- 访问服务器(默认端口是8081)
localhost:8081
- 修改基础配置信息:安装路径下etc目录中nexus-default.properties文件中保存有nexus基础配置信息,例如访问端口
## DO NOT EDIT - CUSTOMIZATIONS BELONG IN $data-dir/etc/nexus.properties
##
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/
# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature
nexus.hazelcast.discovery.isEnabled=true
- 修改服务器运行信息:安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间
-Xms2703m
-Xmx2703m
-XX:MaxDirectMemorySize=2703m
-XX:+UnlockDiagnosticVMOptions
-XX:+LogVMOutput
-XX:LogFile=../sonatype-work/nexus3/log/jvm.log
-XX:-OmitStackTraceInFastThrow
-Djava.net.preferIPv4Stack=true
-Dkaraf.home=.
-Dkaraf.base=.
-Dkaraf.etc=etc/karaf
-Djava.util.logging.config.file=etc/karaf/java.util.logging.properties
-Dkaraf.data=../sonatype-work/nexus3
-Dkaraf.log=../sonatype-work/nexus3/log
-Djava.io.tmpdir=../sonatype-work/nexus3/tmp
-Dkaraf.startLocalConsole=false
#
# additional vmoptions needed for Java9+
#
# --add-reads=java.xml=java.logging
# --add-exports=java.base/org.apache.karaf.specs.locator=java.xml,ALL-UNNAMED
# --patch-module=java.base=lib/endorsed/org.apache.karaf.specs.locator-4.2.6.jar
# --patch-module=java.xml=lib/endorsed/org.apache.karaf.specs.java.xml-4.2.6.jar
# --add-opens=java.base/java.security=ALL-UNNAMED
# --add-opens=java.base/java.net=ALL-UNNAMED
# --add-opens=java.base/java.lang=ALL-UNNAMED
# --add-opens=java.base/java.util=ALL-UNNAMED
# --add-opens=java.naming/javax.naming.spi=ALL-UNNAMED
# --add-opens=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED
# --add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED
# --add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED
# --add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED
# --add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED
# --add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED
#
# comment out this vmoption when using Java9+
#
-Djava.endorsed.dirs=lib/endorsed
2、仓库分类与手动上传组件
-
仓库分类
- 宿主仓库(hosted)
- 保存无法从中央仓库获取的资源
- 自主研发项目
- 第三方未开源项目
- 保存无法从中央仓库获取的资源
- 代理仓库(proxy)
- 代理远程仓库,通过nexus访问其他公共仓库,例如远程仓库
- 仓库组(group)
- 将若干个仓库组成一个群组,简化配置
- 仓库组不能保存资源,与设计型仓库
- 宿主仓库(hosted)
-
在私服上创建仓库
- 宿主仓库:release和snapshot仓库
- 代理仓库:阿里云maven远程仓库
3、本地仓库访问私服
- 配置本地仓库访问私服的权限(setting.xml)
<!--这里是使用用户名/密码访问,也可以使用公钥密钥访问-->
<servers>
<!--私服的release仓库-->
<server>
<id>liyingxi-release</id>
<username>admin</username>
<password>admin</password>
</server>
<!--私服的snapshots地址-->
<server>
<id>liyingxi-snapshot</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
- 配置本地仓库来源(setting.xml)
<mirrors>
<!--访问中央仓库时,使用阿里云的镜像-->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<!--访问其他仓库时,使用私服的仓库组-->
<mirror>
<id>nexus-liyingxi</id>
<mirrorOf>central</mirrorOf>
<name>Nexus liyingxi</name>
<url>https://localhost:8081/repository/maven-public</url>
</mirror>
</mirrors>
4、IDEA访问私服与组件上传
- 在pom.xml中配置项目发布管理
<!--项目发布配置管理-->
<distributionManagement>
<repository>
<!--id需要与setting.xml中的server_id一致-->
<id>liyingxi-release</id>
<url>http://localhost:8081/repository/liyingxi-release/</url>
</repository>
<snapshotRepository>
<!--id需要与setting.xml中的server_id一致-->
<id>liyingxi-snapshot</id>
<url>http://localhost:8081/repository/liyingxi-snapshot/</url>
</snapshotRepository>
</distributionManagement>
- 配置好之后,在IDEA中,执行deploy声明周期,部署到私服