黑马课程
将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享
例如:订单模块和商品模块。订单必然用到商品,如何使商品中的实体类对订单可见?
步骤1:新建一个模块
步骤2:将原Book模块里的domain里面的实体类复制到新的模块maven_pojo里面,并删除Book模块里的domain
步骤3:在Book模块中引入maven_pojo的依赖
<dependency>
<groupId>org.examplegroupId>
<artifactId>maven_pojoartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
步骤4:将maven_pojo模块打包安装到本地仓库中
此后即可正常使用
如何使自己本地仓库里的模块给其他人员使用?——私服
抽取dao层,步骤类似,maven_dao所需的依赖如下
<dependencies>
<dependency>
<groupId>org.examplegroupId>
<artifactId>maven_pojoartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.6version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
dependencies>
依赖传递
A引入B,B引入C,那么A也引入了C,这就是依赖的传递性
依赖冲突
项目引入了同一个依赖的不同版本
可选依赖
<dependency>
<groupId>org.examplegroupId>
<artifactId>maven_pojoartifactId>
<version>1.0-SNAPSHOTversion>
<optional>trueoptional>
dependency>
排除依赖
模块A引入模块B,解决依赖冲突时,可选依赖是从模块B入手,排除依赖是从模块A入手
<dependency>
<groupId>org.examplegroupId>
<artifactId>maven_daoartifactId>
<version>1.0-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>org.examplegroupId>
<artifactId>maven_pojoartifactId>
exclusion>
exclusions>
dependency>
springmvc_ssm中,通过在
在maven_dao中排除掉maven_pojo中的依赖
依赖冲突问题排查
打印所有依赖的依赖树
mvn dependency:tree
# 可以将依赖树输出到文件中
mvn -Dverbose dependency:tree -Doutput=E://depTree.txt
聚合出现背景
聚合就是为了解决上述问题产生的
聚合的思想:通过一个只有pom.xml的空项目,来管理所有的模块,进行自动 install 和 对项目的重新编译
概述
步骤1:创建一个空的maven项目 maven_01_parent
使用01这样的编号更加直观,之前的maven项目也可以改为 maven_02_pojo maven_03_dao
步骤2:在pom.xml中设置打包方式为pom
<packaging>pompackaging>
步骤3: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.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
<modules>
<module>../springmvc_ssmmodule>
<module>../maven_pojomodule>
<module>../maven_daomodule>
modules>
project>
步骤4:使用聚合统一管理项目
对 maven_01_parent 进行 compile,它会将包括自身在内的4个模块一起编译
不管pom.xml添加module的顺序如何,compile都会自动根据依赖关系来决定先后的构建关系
继承是用来解决重复依赖的问题
简化配置
减少版本冲突
步骤1:在子工程中的pom.xml中配置
标签
父工程一般为聚合工程,即maven_01_parent,于是在子工程 springmvc_ssm、maven_pojo、maven_dao 中作如下配置
<parent>
<groupId>org.examplegroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-SNAPSHOTversion>
<relativePath>../maven_01_parent/pom.xmlrelativePath>
parent>
步骤2:优化子项目共有依赖导入问题
将子项目共同使用的jar包都抽取出来,维护在父项目的pom.xml中
删除子项目中被抽取的jar包
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.16version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.6version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>1.3.0version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.2.10.RELEASEversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
步骤3:优化子项目依赖版本问题
上述设置会导致子项目多出很多不需要的依赖
例如 maven_domain 模块不需要引入任何依赖,但配置父项目后,就包括了父项目中的全部依赖
可以通过
来优化管理,以依赖 junit 为例
在父工程中删除 junit 依赖,同时添加如下依赖管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
dependencyManagement>
在需要用到 junit 的子项目中,引入依赖
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
注意!子项目中引入依赖时不再需要写 version,从而实现统一依赖版本
需求:希望将所有版本为5.2.10.RELEASE的依赖改为5.1.9.RELEASE
步骤1:父工程中定义属性
<properties>
<spring.version>5.2.10.RELEASEspring.version>
<junit.version>4.12junit.version>
properties>
步骤2:修改依赖的version
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${spring.version}version>
dependency>
需求:在之前的springmvc_ssm项目中,有一个jdbc.properties的配置文件,里面定义了driver, url, username, password 这4个属性
现在希望通过maven_01_parent来管理jdbc.properties里面的属性值
步骤1:父工程定义属性
<properties>
...
<jdbc.url>jdbc:mysql://localhost:3306/ssm_db?useSSL=false&useServerPrepStmts=truejdbc.url>
properties>
步骤2:设置maven过滤文件范围
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resourcesdirectory>
<filtering>truefiltering>
resource>
resources>
build>
说明:
../springmvc_ssm/src/main/resources 只管理springmvc_ssm里面的resources
${project.basedir}/src/main/resources 管理所有模块的resources
如果希望只管理某几个子项目,可以写多个标签
步骤3:jdbc.properties文件中引用属性
# 子模块中
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=123456
刷新maven,可以看到项目结构的变化
步骤4:测试是否生效
install命令将springmvc_ssm打成war包,在本地仓库找到对应的war包
在路径 springmvc_ssm-1.0-SNAPSHOT.war\WEB-INF\classes
中打开生成的jdbc.properties,可以看到 jdbc.url 的值已经被添加
运行项目,正常执行
注意
如果缺乏web.xml文件,打包时可能报错:Error assembling WAR: webxml attribute is required
可以通过将web.xml添加上去解决,也可以通过以下命名忽略web.xml的检查
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-war-pluginartifactId>
<version>3.2.3version>
<configuration>
<failOnMissingWebXml>falsefailOnMissingWebXml>
configuration>
plugin>
plugins>
build>
查看属性:在cmd窗口中输入
mvn help:system #查看所有属性
在程序中使用某个属性,只需要
${java.runtime.name}
在jar包的版本定义中,有两个工程版本用的比较多:
此外还经常能看到一些发布版本:
在maven_01_parent里面配置多环境
需要删除之前在属性里配置的jdbc.url,然后再加入以下配置
<profiles>
<profile>
<id>env_depid>
<properties>
<jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db?useSSL=false&useServerPrepStmts=truejdbc.url>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
<profile>
<id>env_proid>
<properties>
<jdbc.url>jdbc:mysql://127.2.2.1:3306/ssm_db?useSSL=false&useServerPrepStmts=truejdbc.url>
properties>
profile>
<profile>
<id>env_testid>
<properties>
<jdbc.url>jdbc:mysql://127.3.3.1:3306/ssm_db?useSSL=false&useServerPrepStmts=truejdbc.url>
properties>
profile>
profiles>
上述设定默认的启动环境是开发环境
也可以通过以下命令动态指定环境
mvn install -P env_test
如果在测试环境使用install,那么所有的test都将依次执行
当部分模块还没有开发完毕,但需要对已经开发完毕的打包时,就无法完成。此时需要跳过测试
应用场景
方法一:IDEA工具实现跳过测试
此时执行install,由于跳过了测试,程序里的 BookServiceTest 不会被执行
方法二:配置插件实现跳过测试
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.12.4version>
<configuration>
<skipTests>falseskipTests>
<excludes>
<exclude>**/BookServiceTest.javaexclude>
excludes>
configuration>
plugin>
plugins>
build>
方法三:命令行跳过测试
mvn package -D skipTests
注意:cmd要在pom.xml所在目录下进行执行
A,B,C合作开发项目,如果B想要使用A开发的模块,就需要用到私服
私服:公司内部搭建的用于存储Maven资源的服务器
远程仓库/中央仓库:Maven开发团队维护的用于存储Maven资源的服务器
Nexus
官网下载(慢)
下载地址:https://help.sonatype.com/repomanager3/download)
百度云盘下载
链接:https://pan.baidu.com/s/1nFgGeDtSL-e0np3BpB7YRQ
提取码:ar7m
安装
说明
nexus文件夹中的nexus.vmoptions中定义了sonatyoe-work的地址,用到了后者的一些配置,因此这两个文件夹都需要保留
在bin目录下打开cmd,执行
nexus.exe /run nexus
访问 http://localhost:8081
首次使用需要点击 sign up,根据提示到指定位置找到密码,然后登录
登录成功后,根据提示进行设置
这里登录之后可能会报一个:java.net.UnknownHostException: sonatype-download.global.ssl.fastly.net
导致结果:能正常使用nexus基础功能,但无法正常关闭
可能的原因:官网进不去导致的
暂时的解决方法:关闭拓展
关闭这里常无法关闭,建议先关闭页面,再关闭nexus
方法一:ctrl+c
方法二:命令行
在nexus.exe路径下另启一个cmd窗口,输入以下命令
nexus.exe /stop nexus
方法三:点 x 强制关闭(不推荐)
私服里有多个仓库,这些仓库分为三大类
宿主仓库hosted
保存无法从中央仓库获取的资源
代理仓库proxy
每次去中央仓库下载,速度慢,代理仓库可用于专门存储从远程中央仓库下载的第三方jar包
仓库组group
私服里有宿主仓库,有存放SNAPSHOT的代理仓库,有存放RELEASE类型的代理仓库……
为了设置获取资源时在哪个仓库中获取,可以将所有的仓库编成一个组,只需要访问仓库组去获取资源
之前的web项目,实际上用的是阿里云私服
创建新的仓库
仓库类型选择maven2 (hosted)
,设置仓库名称和存储的jar包类型
创建好personal-snapshot后,同样的方式再创建一个personal-release,只将Version policy改为Release即可
在配置文件setting.xml中配置
<servers>
<server>
<id>personal-snapshotid>
<username>adminusername>
<password>123456password>
server>
<server>
<id>personal-releaseid>
<username>adminusername>
<password>123456password>
server>
servers>
<mirrors>
<mirror>
<id>maven-publicid>
<mirrorOf>*mirrorOf>
<url>http://localhost:8081/repository/maven-public/url>
mirror>
mirrors>
步骤1:在项目maven-01-parent的pom.xml中配置
<distributionManagement>
<repository>
<id>personal-releaseid>
<url>http://localhost:8081/repository/personal-release/url>
repository>
<snapshotRepository>
<id>personal-snapshotid>
<url>http://localhost:8081/repository/personal-snapshot/url>
snapshotRepository>
distributionManagement>
要发布的项目都需要配置distributionManagement
标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可
步骤2:deploy 上传到私服
注意,此时已经更改为从私服获取jar,当第一次上传时,由于私服的代理仓库maven-central
为空,必然花费一定时间去下载 maven-01-parent 里面用到的所有jar包到私服中去
步骤3:查看私服中仓库 personal-release 和 personal-snapshot
可以看到personal-snapshot里面已经有上传的项目了,然而personal-release里面依然为空
这是因为maven_01_parent的pom.xml里面设置了当前项目为
<groupId>org.examplegroupId>
<artifactId>maven_01_parentartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>pompackaging>
如果将其改为
,即可上传到仓库personal-release里面去
注意:子工程也要修改为RELEASE,否则子项目会被发布到personal-snapshot当中去
步骤4(非必要):配置私服去阿里云中下载依赖
如果私服中没有对应的jar,会去中央仓库下载,如果速度可能太慢,可以配置让私服去阿里云中下载依赖
如果需要修改,可改为:https://maven.aliyun.com/repository/public
下载资源同之前一样,直接在pom.xml里面引入坐标即可