Maven学习笔记 学习来源:黑马教程
学习时间:2022年1月21日
1 Maven简介 1.1 传统项目管理状态分析
jar包不统一,不兼容
工程升级维护过程操作繁琐
…
1.2 Maven是什么
maven的本质是一个项目管理工具 ,将项目开发和管理过程抽象成一个项目对象模型 (POM)
POM(Project Object Model):项目对象模型
1.3 Maven的作用
项目构建 :提供标准的、跨平台的自动化项目构建方式
依赖管理 :方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题
统一的开发结构 :提供标准的、统一的项目结构
2 下载与安装
将下载好的文件解压缩,我的是放在C:\Program Files\apache-maven-3.6.3
下
配置环境变量:
在cmd查看是否配置成功:
3 Maven基础概念 3.1 仓库
仓库分类
本地仓库 :自己电脑上存储资源的仓库,连接远程仓库获取资源
远程仓库 :包括私服和中央仓库,即非本机电脑上的仓库,为本地仓库提供资源
中央仓库:Maven团队维护,存储所有资源的仓库
私服:部门或公司范围内存储资源的仓库,它从中央仓库来获取资源
私服的作用
保存具有版本的资源,包含购买或自主研发的jar
中央仓库的jar都是开源的,不能存储具有版权的资源
一定范围内共享资源,仅对内部开放,不对外共享
3.2 坐标
坐标:Maven中的坐标用于描述仓库中资源的位置
主要组成:
groupId
:定义当前Maven项目隶属组织名称(通常是域名反写 ,例如org.mybatis
)
artifactId
:定义当前Maven项目名称(通常是模块名称,例如CRM,SMS)
version
:定义当前项目版本号
packaging
:定义该项目的打包方式
示例:
1 2 3 4 5 <dependency > <groupId > org.elasticsearch.client</groupId > <artifactId > elasticsearch-rest-high-level-client</artifactId > <version > 7.12.1</version > </dependency >
作用:使用唯一标识,唯一性地定位资源位置,通过该标识可以将资源的识别与下载工作交由机器完成
3.3 仓库配置 3.3.1 本地仓库配置 Maven启动后,会自动保存下载的资源到本地仓库,仓库位置可在conf/settings.xml
下查看
其中的默认位置就是:
1 <localRepository > ${user.home}/.m2/repository</localRepository >
可以自定义本地仓库的位置,将上述代码修改为:
1 <localRepository > D:/DevEnvironment/localRepository</localRepository >
3.3.2 远程仓库配置 Maven默认连接的远程仓库的位置:
1 2 3 4 5 6 7 8 9 10 11 <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 >
可以将其替换为镜像仓库,修改conf/settings.xml
,配置为阿里云的镜像仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 <mirrors > <mirror > <id > nexus-aliyun</id > <mirrorOf > central</mirrorOf > <name > Nexus aliyun</name > <url > http://maven.aliyun.com/nexus/content/groups/public</url > </mirror > </mirrors >
4 手工制作Maven项目 4.1 项目结构搭建
Maven工程目录结构
代码
在src/main/java/com/hongyi/
下新建Demo.java
1 2 3 4 5 6 7 package com.hongyi;public class Demo { public String say (String name) { System.out.println("Hello, " + name); return "Hello, " + name; } }
在src/test/java/com/hongyi/
下新建DemoTest.java
1 2 3 4 5 6 7 8 9 10 11 12 package com.hongyi;import org.junit.Test;import org.junit.Assert;public class DemoTest { @Test public void testSay () { Demo d = new Demo (); String ret = d.say("Maven" ); Assert.assertEquals("Hello, Maven" , ret); } }
在项目根目录(和src
同级)下新建一个pom.xml
文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?xml version="1.0" encoding="UTF-8" ?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.hongyi</groupId > <artifactId > project-maven</artifactId > <version > 1.0</version > <packaging > jar</packaging > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency > </dependencies > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > </properties > </project >
4.2 项目构建 Maven常用构建命令:使用mvn
开头,后面添加功能参数,可以一次执行多个命令,使用空格分隔
命令
作用
mvn compile
编译,生成target文件
mvn clean
清理target文件
mvn test
测试
mvn package
打包,包含编译和测试,生成jar包
mvn install
将jar包安装到本地仓库
使用示例
进入到项目根目录,运行编译命令
如果jdk版本指定过低,会报以下错误:
此时查看本地仓库,会有下载好的资源
此时,在项目根目录中也会有编译完成的项目target
:
执行clean
命令,会清除target
目录
执行test
命令,也会编译生成target
,并且附带有测试结果文件
测试报告:
执行package
命令,会将源程序编译并打包
注意:打包命令包含了编译和测试两个命令。
执行install
命令,会将该项目安装到本地仓库
查看本地仓库,按照项目的groupId
查找,例如com.hongyi
:
其中项目名称artifactId
又决定了一层目录,这里为project-maven
:
版本号version
又决定了一层目录:
最后的文件内容,即为打好包的jar包和对应的pom文件:
5 IDEA生成Maven项目 5.1 创建空Maven项目
新建一个空的工程,然后选择jdk版本
打开setting
,搜索maven
并进行相关配置:
新建模块module
:
然后标记各个目录的功能:
在idea右侧有maven相关的操作:
与mvn的各种命令相同,不再赘述。
按照上一节的操作,添加各个类,最后的项目结构如下:
5.2 使用骨架创建Maven项目
新建一个模块。选择骨架创建maven项目,这里选择quick-start
项目结构如下:
按照maven项目的经典结构进行改造,改造后的结果如下:
6 依赖管理 6.0 project和module的关系 在 IntelliJ IDEA 中Project是最顶级的结构单元,然后就是Module,一个Project可以有多个Module。目前,主流的大型项目结构基本都是多Module的结构,这类项目一般是按功能划分的,比如:user-core-module
、user-facade-module
和user-hessian-module
等等,模块之间彼此可以相互依赖。通过这些Module的命名可以看出,它们都是处于同一个项目中的模块,彼此之间是有着不可分割的业务关系。因此,我们可以大致总结出:一个Project是由一个或多个Module组成 :
当为单Module
项目的时候,这个单独的Module
实际上就是一个Project
;
当为多Module
项目的时候,多个模块处于同一个Project
之中,此时彼此之间具有互相依赖的关联关系。
简单地理解Project就是一个单纯的目录 ,只是这个目录在命名上必须有其代表性的意义。在缺省情况下,IntelliJ IDEA 是默认单Project单Module的,这时Project和Module合二为一。
.idea
文件夹在那个文件夹,则此文件夹为Project文件夹
6.1 项目搭建
创建三个maven模块,project1
,project2
,project3
,分别添加log4j的依赖,版本号依次为2.13.0
,2.13.1
,2.13.2
,项目结构如下:
各个模块的maven依赖如下:
6.2 依赖配置
依赖:指当前项目运行所需的jar,一个项目可以设置多个依赖
格式:
1 2 3 4 5 6 7 8 9 10 11 12 <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency > </dependencies >
6.3 依赖传递 6.3.1 概念
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被依赖的资源如果依赖其他资源,则当前项目间接依赖其他资源
6.3.2 依赖传递的冲突问题
路径优先:当依赖中出现相同的资源,层级越深,优先级越低,反之越高
声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖靠后的
特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的
示例
project2
依赖project3
:
1 2 3 4 5 6 <dependency > <groupId > com.hongyi</groupId > <artifactId > project3</artifactId > <version > 1.0-SNAPSHOT</version > </dependency >
在project3
中添加junit
的依赖
1 2 3 4 5 <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency >
查看此时的依赖关系
对当前项目project2
而言,project3
和log4j:2.13.1
为1度依赖,而project3
的log4j:2.13.2
为2度依赖,因此被忽略(omitted
)
6.3.3 可选依赖 可选依赖是指对外隐藏当前所依赖的资源,即不透明性。配置是在被依赖方 。
1 2 3 4 5 6 7 <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > <optional > true</optional > </dependency >
发现该依赖被隐藏了。
6.3.4 排除依赖 排除依赖是主动 断开依赖的资源,被排除的资源不需要指定版本。配置是在依赖方 。
例如project2
要排除掉project3
中的依赖log4j:2.13.2
(虽然根据依赖冲突的解决也没有生效)。在project2
的pom文件中添加:
1 2 3 4 5 6 7 8 9 10 11 12 <dependency > <groupId > com.hongyi</groupId > <artifactId > project3</artifactId > <version > 1.0-SNAPSHOT</version > <exclusions > <exclusion > <groupId > org.apache.logging.log4j</groupId > <artifactId > log4j-core</artifactId > </exclusion > </exclusions > </dependency >
执行结果:
发现project2
中没有了log4j:2.13.2
的依赖。只剩下junit
的依赖
6.4 依赖范围 6.4.1 概述 依赖的jar默认情况可以在任何地方使用,可以通过scope
标签设定其作用范围
作用范围
主程序范围有效(main文件范围内)
测试程序范围有效(test文件范围内)
是否参与打包(package指令范围内)
scope
主代码
测试代码
打包
示例
compile
(默认)
√
√
√
log4j
test
√
junit
provided
√
√
servlet-api
runtime
√
jdbc
示例
例如在project2
中新增依赖:
1 2 3 4 5 6 <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.9</version > <scope > test</scope > </dependency >
执行结果:
6.4.2 依赖范围传递性 带有依赖范围的资源在进行传递时,作用范围将受到影响。
7 生命周期与插件 7.1 项目构建生命周期 Maven构建生命周期描述的是一次构建过程经历了多少个事件
Maven对项目构建的生命周期划分为3套:
clean
:清理工作
default
:核心工作,例如编译,测试,打包,部署等
site
:产生报告,发布站点
clean生命周期
pre-clean
:执行一些需要在clean之前完成的工作
clean
:
移除所有上一次构建生成的文件
post-clean
:执行一些需要在clean之后立刻完成的工作
default构建生命周期
说明:图中标红的是Maven典型(常用)的构建生命周期点。
例如当执行mvn compile
命令时,会从头(mvn validate
)开始执行命令至mvn compile
初。
又如执行mvn package
命令时,也会从头开始执行,直到mvn package
命令处停止。
site构建生命周期
7.2 插件
插件与生命周期内的阶段绑定 ,在执行到对应生命周期时执行对应的插件功能
默认maven在各个生命周期上绑定有预设的功能
通过插件可以自定义其他功能
在官网中可以查阅到各种插件:
理解:生命周期相当于人活到了几岁,而插件相当于在几岁时需要做哪些事情。
演示示例——自定义插件
项目搭建:在project3
中的主类和测试类中分别创建Demo.java
和DemoTest.java
1 2 3 4 5 public class Demo { public void run () { System.out.println("source code plugin..." ); } }
1 2 3 4 5 public class DemoTest { public void test () { System.out.println("test source code plugin..." ); } }
自定义插件 写在<bulid>
标签中。在project3
的pom文件中写入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <build > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-source-plugin</artifactId > <version > 3.2.1</version > <executions > <execution > <goals > <goal > jar</goal > </goals > <phase > generate-test-resources</phase > </execution > </executions > </plugin > </plugins > </build >
此处演示在generate-test-resources
处自定义了一个插件,该插件生成项目的源码文件。意味着,例如执行mvn test
时,会执行到该插件。执行mvn compile
时,不会执行到该插件。而且该插件只会生成main中的源代码。
刷新maven后,可看到该插件:
执行mvn compile
,发现target并没有生成源码文件
执行mvn test
,发现生成了源码文件
打开文件,发现是main的源码:
添加一个goal
为test-jar
。首先执行clean
,再执行package
:
发现有打包好的工程文件、main源码和test源码。
7.3 spring-boot-maven-plugin 7.3.1 简介 spring-boot-maven-plugin
是一个 Maven 插件,专门为 Spring Boot 项目设计,用于简化 Spring Boot 应用程序的构建和部署。
功能
重新打包 :使用 repackage
目标将 Spring Boot 应用重新打包为一个可执行 JAR 或 WAR 文件,包含所有依赖项,使得应用可以直接运行。
运行应用 :使用 spring-boot:run
目标在开发过程中直接运行 Spring Boot 应用,简化开发和测试流程。
构建镜像 :支持将 Spring Boot 应用打包为 Docker 镜像,通过 spring-boot:build-image
目标简化 Docker 镜像构建过程。
生成应用特定的构建信息 :在构建过程中自动生成 build-info.properties
文件,包含版本、时间戳等构建信息。
引入:
1 2 3 4 5 6 7 8 9 10 <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > <finalName > app</finalName > </build >
刷新maven:
7.3.2 普通方式打包 现在删除上面的配置,刷新maven,再点击package
:
发现jar包的大小只有几kb,且运行后报错:
原因:一般的maven项目的打包命令,不会把依赖的jar包也打包进去的,只是会放在jar包的同目录下,能够引用就可以了。
7.3.3 插件打包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <executions > <execution > <goals > <goal > repackage</goal > </goals > </execution > </executions > </plugin > </plugins > <finalName > app</finalName > </build >
原因:spring-boot-maven-plugin
插件,会将依赖的jar包全部打包进去。该文件包含了所有的依赖和资源文件,可以直接在命令行或者传统的 Java Web 服务器上启动运行。
默认情况下,repackage命令所生成的包,会把项目中所有的依赖都打进去。但其实在项目中scope为provided的依赖,比如 lombok、mybatis-plus等,只作用于编译阶段,编译完成就没用了。若除去provided依赖,可以使用如下的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <executions > <execution > <goals > <goal > repackage</goal > </goals > </execution > </executions > <configuration > <excludes > <exclude > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > </exclude > </excludes > </configuration > </plugin > </plugins > <finalName > app</finalName > </build >
7.3.4 JAR包结构 在 Spring Boot 应用的可执行 JAR 文件中,通常包含以下几个关键目录:BOOT-INF
、META-INF
和 org
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 my-spring-boot-app.jar/ ├── BOOT-INF/ │ ├── classes/ │ │ ├── com/ │ │ │ └── example/ │ │ │ └── MyApplication.class │ │ └── application.properties │ └── lib/ │ ├── spring-boot-starter-2.5.5.jar │ └── other-dependencies.jar ├── META-INF/ │ ├── MANIFEST.MF │ └── other-metadata-files └── org/ └── springframework/ └── boot/ └── autoconfigure/ └── ...
① BOOT-INF 1 2 3 4 5 6 7 8 9 BOOT-INF/ ├── classes/ │ ├── com/ │ │ └── example/ │ │ └── MyApplication.class │ └── application.properties └── lib/ ├── spring-boot-starter-1.5.9.RELEASE.jar └── other-dependencies.jar
BOOT-INF
目录是 Spring Boot 特有的目录结构,用于包含应用的主要内容和依赖项。这个目录通常包含两个子目录:
BOOT-INF/classes
:包含编译后的应用程序类文件和资源文件。这是你编写的 Java 类文件被放置的地方。
BOOT-INF/lib
:包含所有应用程序的依赖 JAR 文件。这些依赖项会在运行时被包含在类路径中。
1 2 3 META-INF/ ├── MANIFEST.MF └── other-metadata-files
META-INF
目录包含 JAR 文件的元数据和配置信息。这个目录通常包含一些标准文件和目录:
MANIFEST.MF
:包含 JAR 文件的清单信息,包括版本、主类等元数据。
其他可能的文件和目录:如服务提供者配置文件、持久性配置文件等。
MANIFEST.MF
文件的内容示例:
1 2 3 4 Manifest-Version: 1.0 Main-Class: com.example.MyApplication Start-Class: com.example.MyApplication Spring-Boot-Version: 2.5.5
③ org 1 2 3 4 5 org/ └── springframework/ └── boot/ └── autoconfigure/ └── ...
org
目录通常包含 Spring Boot 自身和其他依赖库的类文件。这个目录会在解压后的依赖 JAR 文件中看到,它不是 Spring Boot 应用特有的,但常见于依赖库的包名。
综上,这些目录和文件共同构成了一个可执行的 Spring Boot JAR 文件,使得应用能够独立运行而不依赖于外部环境。
8 分模块开发与设计 8.1 目标 目标:将ssm项目拆分。
如上图所示,将ssm项目拆分成右侧几个模块。
8.2 ssm-pojo拆分
新建一个maven项目模块
拷贝原始项目中对应的相关代码到该模块中,删除不必要的测试类和配置文件
这个模块的pom没有依赖任何资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="UTF-8" ?> <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.itheima</groupId > <artifactId > ssm_pojo</artifactId > <version > 1.0-SNAPSHOT</version > <properties > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > </properties > </project >
8.3 ssm_dao拆分
新建模块ssm_dao,拷贝原始项目中对应的相关代码到该模块中,删除不必要的测试类和非dao层的配置文件。
对于dao层的pom文件内容如下(即所需的资源):注意ssm_pojo资源的导入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 <dependencies > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_pojo</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > 5.1.9.RELEASE</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.3</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-jdbc</artifactId > <version > 5.1.9.RELEASE</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis-spring</artifactId > <version > 2.0.3</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.16</version > </dependency > <dependency > <groupId > com.github.pagehelper</groupId > <artifactId > pagehelper</artifactId > <version > 5.1.2</version > </dependency > </dependencies >
运行mvn compile
发现构建失败:
原因在于,导入了ssm_pojo的资源坐标,但是在本地仓库中没有这个资源,因此需要对ssm_pojo项目进行mvn install
,将其安装到本地仓库:
然后再对ssm_dao进行编译,通过。
对dao的配置文件applicationContext.xml
进行修改,删去非dao层的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:context ="http://www.springframework.org/schema/context" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="com.itheima" /> <context:property-placeholder location ="classpath*:jdbc.properties" /> <bean id ="dataSource" class ="com.alibaba.druid.pool.DruidDataSource" > <property name ="driverClassName" value ="${jdbc.driver}" /> <property name ="url" value ="${jdbc.url}" /> <property name ="username" value ="${jdbc.username}" /> <property name ="password" value ="${jdbc.password}" /> </bean > <bean class ="org.mybatis.spring.SqlSessionFactoryBean" > <property name ="dataSource" ref ="dataSource" /> <property name ="typeAliasesPackage" value ="com.itheima.domain" /> <property name ="plugins" > <array > <bean class ="com.github.pagehelper.PageInterceptor" > <property name ="properties" > <props > <prop key ="helperDialect" > mysql</prop > <prop key ="reasonable" > true</prop > </props > </property > </bean > </array > </property > </bean > <bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer" > <property name ="basePackage" value ="com.itheima.dao" /> </bean > </beans >
8.4 ssm_service拆分
新建模块ssm_service,拷贝原始项目中对应的相关代码到该模块中,删除不必要的非service层的配置文件。注意保留测试类test。
对于service层的pom文件内容如下(即所需的资源):注意ssm_dao资源的导入,此外无需导入ssm_pojo的资源,因为他间接依赖 了ssm_dao的ssm_pojo资源。对ssm_dao进行install
命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <dependencies > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_dao</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > 5.1.9.RELEASE</version > </dependency > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-test</artifactId > <version > 5.1.9.RELEASE</version > </dependency > </dependencies >
对ssm_service的配置文件applicationContext.xml
进行修改,删去非service层的代码,此外将其修改为applicationContext-service.xml
。同理将ssm_dao的配置文件名修改为applicationContext-dao.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:context ="http://www.springframework.org/schema/context" xmlns:tx ="http://www.springframework.org/schema/tx" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" > <context:component-scan base-package ="com.itheima" /> <tx:annotation-driven transaction-manager ="txManager" /> <bean id ="txManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name ="dataSource" ref ="dataSource" /> </bean > </beans >
修改单元测试引入的配置文件名,由单个文件修改为多个文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext-service.xml", "classpath:applicationContext-dao.xml"}) public class UserServiceTest { @Autowired private UserService userService; @Test public void testSave () { User user = new User (); user.setUserName("Jock" ); user.setPassword("root" ); user.setRealName("Jockme" ); user.setGender(1 ); user.setBirthday(new Date (333333000000L )); userService.save(user); } @Test public void testDelete () { User user = new User (); userService.delete(2 ); } @Test public void testUpdate () { User user = new User (); user.setUuid(1 ); user.setUserName("Jockme" ); user.setPassword("root" ); user.setRealName("JockIsMe" ); user.setGender(1 ); user.setBirthday(new Date (333333000000L )); userService.update(user); } @Test public void testGet () { User user = userService.get(1 ); System.out.println(user); } @Test public void testGetAll () { PageInfo<User> all = userService.getAll(2 , 2 ); System.out.println(all); System.out.println(all.getList().get(0 )); System.out.println(all.getList().get(1 )); } @Test public void testLogin () { User user = userService.login("Jockme" , "root" ); System.out.println(user); } }
运行mvn test
进行用例测试,通过。最后执行mvn install
,将service层代码安装到本地仓库中。
8.5 ssm_controller拆分
利用骨架webapp新建maven模块ssm_controller。拷贝原始项目中对应的相关代码到该模块中,删除不必要的非controller层的配置文件。
对于controller层的pom文件内容如下(即所需的资源):注意ssm_service资源的导入和间接依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <dependencies > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_service</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.1.9.RELEASE</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.9.0</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > <scope > provided</scope > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.apache.tomcat.maven</groupId > <artifactId > tomcat7-maven-plugin</artifactId > <version > 2.1</version > <configuration > <port > 80</port > <path > /</path > </configuration > </plugin > </plugins > </build >
修改web.xml
中的加载spring环境的配置文件(dao层和service层),使用*
进行通配
1 2 3 4 <context-param > <param-name > contextConfigLocation</param-name > <param-value > classpath*:applicationContext-*.xml</param-value > </context-param >
配置tomcat服务器并使用postman测试:http://localhost:8080/user?userName=Mark&password=123456&realName=Hongyi&gender=1&birthday=2022/01/06
数据库中:
8.6 小结 分模块开发:
模块中仅包含 当前模块对应的功能类与配置文件
spring核心配置根据模块功能不同进行独立制作
当前模块所依赖的模块通过导入坐标的形式加入当前模块后才可以使用
web.xml需要加载所有的spring核心配置文件
9 聚合和继承 9.1 聚合 聚合:多模块的构建维护。
聚合作用:聚合用于快速构建maven工程,一次性 构建多个项目或模块
示例
创建一个空模块ssm
,该项目中只有一个pom文件
打包类型定义为pom,并定义当前模块进行构建时关联的其他模块名称
1 2 3 4 5 6 7 8 9 10 <packaging > pom</packaging > <modules > <module > ../ssm_dao</module > <module > ../ssm_pojo</module > <module > ../ssm_controller</module > <module > ../ssm_service</module > </modules >
注意:参与聚合操作的模块最终执行顺序与模块间的依赖关系有关,与配置顺序无关
执行mvn install
并观察:
9.2 继承 9.2.1 概述和示例 继承:模块依赖关系维护。
继承作用:通过继承可以实现在子工程中沿用父工程的配置
maven中的继承与java中的继承相似,在子工程中配置继承关系
示例
在父工程ssm
中声明依赖管理,将子工程所有的依赖都声明在此处。利用标签<dependencyManagement>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <dependencyManagement > <dependencies > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_pojo</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_dao</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_service</artifactId > <version > 1.0-SNAPSHOT</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.1.9.RELEASE</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.9.0</version > </dependency > </dependencies > </dependencyManagement >
在子工程中定义父工程
1 2 3 4 5 6 7 8 9 <parent > <artifactId > ssm</artifactId > <groupId > com.itheima</groupId > <version > 1.0-SNAPSHOT</version > <relativePath > ../ssm/pom.xml</relativePath > </parent >
此时,子工程的依赖的版本号可以省略,例如:
1 2 3 4 5 <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_pojo</artifactId > </dependency >
同理,插件的管理也可以在父工程中声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <build > <pluginManagement > <plugins > <plugin > <groupId > org.apache.tomcat.maven</groupId > <artifactId > tomcat7-maven-plugin</artifactId > <version > 2.1</version > <configuration > <port > 80</port > <path > /</path > </configuration > </plugin > </plugins > </pluginManagement > </build >
子工程中插件的版本和相关配置就可以省略
1 2 3 4 5 6 7 8 9 10 <build > <plugins > <plugin > <groupId > org.apache.tomcat.maven</groupId > <artifactId > tomcat7-maven-plugin</artifactId > </plugin > </plugins > </build >
9.2.2 继承的资源 以下资源,子工程都可以从父工程中继承:
9.2.3 继承和聚合的区别
作用:
相同点:
聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中
聚合与继承均属于设计型模块,并无实际的模块内容
不同点:
聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
9.3 属性 9.3.1 自定义属性
作用:等同于定义变量,方便统一维护
配置位置:父工程的pom文件
标签:<properties>
调用格式:${ }
示例
在父工程中的pom文件内:
1 2 3 4 5 6 7 8 <properties > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > <spring.version > 5.1.9.RELEASE</spring.version > <junit.version > 4.12</junit.version > </properties >
调用:
1 2 3 4 5 6 <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${spring.version}</version > </dependency >
9.3.2 内置属性
例如,父工程和子工程的版本号一样,可以直接使用父工程的版本内置属性${version}
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_pojo</artifactId > <version > ${version}</version > </dependency > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_dao</artifactId > <version > ${version}</version > </dependency > <dependency > <groupId > com.itheima</groupId > <artifactId > ssm_service</artifactId > <version > ${version}</version > </dependency >
9.3.3 其他属性 其他的属性类别还有Setting属性、Java系统属性、环境变量属性,了解即可。
9.4 版本管理 9.4.1 工程版本区分
SNAPSHOT
快照版本
项目开发过程中,为方便团队成员合作,解决模块间相互依赖和时时更新的问题,开发者对每个模块进行构建的时候,输出的临时性版本叫快照版本(测试阶段版本)
快照版本会随着开发的进展不断更新
RELEASE
发布版本
项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
9.4.2 工程版本号约定
约定规范:
<主版本>.<次版本>.<增量版本>.<里程碑版本>
主版本∶表示项目重大架构的变更,如∶spring5相较于spring4的迭代次版本∶表示有较大的功能增加和变化,或者全面系统地修复漏洞
增量版本∶表示有重大漏洞的修复
里程碑版本∶表明一个版本的里程碑(版本内部)。这样的版本同下一个正式版本相比,相对来说不是很稳定,有待更多的测试
范例:
9.5 资源配置 资源配置多文件维护:
配置文件引用pom属性:
作用:在任意配置文件中加载pom文件中定义的属性
调用格式:${ }
示例
例如jdbc.properties
要读取父工程pom文件中的属性。首先在父工程pom文件中的<build>
标签中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <bulid > <resources > <resource > <directory > ${project.basedir}/src/main/resources</directory > <filtering > true</filtering > </resource > </resources > <testResources > <testResource > <directory > ${project.basedir}/src/test/resources</directory > <filtering > true</filtering > </testResource > </testResources > </bulid >
设置属性:
1 2 3 4 5 6 7 8 <properties > <maven.compiler.source > 11</maven.compiler.source > <maven.compiler.target > 11</maven.compiler.target > <spring.version > 5.1.9.RELEASE</spring.version > <junit.version > 4.12</junit.version > <jdbc.url > jdbc:mysql://127.0.0.1:3306/ssm_db?useSSL=false</jdbc.url > </properties >
jdbc.properties
内容:
1 2 3 4 5 jdbc.driver =com.mysql.jdbc.Driver jdbc.url =${jdbc.url} jdbc.username =root jdbc.password =12345678
9.6 多环境开发配置 多环境兼容:
配置方法
在父工程pom文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <profiles > <profile > <id > pro_env</id > <properties > <jdbc.url > jdbc:mysql://127.0.0.1:3306/ssm_db?useSSL=false</jdbc.url > </properties > </profile > <profile > <id > dev_env</id > <properties > <jdbc.url > jdbc:mysql://127.0.0.2:3306/ssm_db?useSSL=false</jdbc.url > </properties > <activation > <activeByDefault > true</activeByDefault > </activation > </profile > </profiles >
加载指定的环境
例如:新建一个maven配置,在开发环境执行install命令:
执行后查看jdbc.properties
文件:
可见是按照开发环境的地址127.0.0.2
进行项目安装的。
9.7 跳过测试
应用场景
整体模块功能未开发
模块中某个功能未开发完毕
单个功能更新调试导致其他功能失败
快速打包(因为测试需要耗费时间)
…
使用操作界面跳过测试
10 Maven私服 分模块合作开发:
10.1 Nexus私服搭建
Nexus是Sonatype
公司的一款maven私服产品
下载地址∶https∶//help.sonatype.com/repomanager3/download
搭建步骤
服务器首先必须配置好java的环境
将下载好的压缩包解压缩至任意位置
nexus服务所需内存等参数位于/bin/nexus.vmoptions
中
nexus服务的端口等参数设置位于/etc/nexus-default.properties
中
配置环境变量并刷新
1 2 export NEXUS_HOME=/usr/local/nexus #nexus的目录 export RUN_AS_USER=root
进入nexus目录并运行
访问配置好的端口网址即可
停止服务运行
10.2 Nexus操作 10.2.1 仓库分类和手工资源上传 私服资源的获取:下图所示,我们要把快照版的资源放在一个仓库里,把发行版的资源放在一个仓库里,第三方公共资源放在一个仓库里,这样方便进行管理,势必要对仓库进行分类和分组 。
仓库分类
宿主仓库hosted
:保存无法从中央仓库获取的资源
代理仓库proxy
:代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库
仓库组group
:
将若干仓库组成一个群组,简化配置
仓库组不能保存资源 ,属于设计型仓库
操作实例
新建一个仓库,例如heima-release
仓库类型选择宿主仓库maven2(hosted)
创建好后,将其加入到maven-public
仓库组中,方便管理
将ssm_pojo打包好的jar文件上传至heima-release
仓库中
查看仓库里的ssm_pojo资源
10.2.2 本地仓库访问私服 idea环境中的资源上传与下载:
配置本地仓库访问私服的权限(setting.xml
)
1 2 3 4 5 6 7 8 9 10 11 12 <server > <id > heima-release</id > <username > admin</username > <password > XXXXXXXXX</password > </server > <server > <id > heima-snapshot</id > <username > admin</username > <password > XXXXXXXXX</password > </server >
配置本地仓库资源的下载来源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <mirror > <id > nexus-aliyun</id > <name > nexus-aliyun</name > <url > http://maven.aliyun.com/nexus/content/groups/public</url > <mirrorOf > central</mirrorOf > </mirror > <mirror > <id > heima</id > <url > XXXXXXXXXXXX</url > <mirrorOf > *</mirrorOf > </mirror >
配置当前项目ssm
访问私服上传资源的保存位置(pom.xml
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <distributionManagement > <repository > <id > heima-release</id > <url > http://XXXXXXX/repository/heima-release/</url > </repository > <snapshotRepository > <id > heima-snapshot</id > <url > http://XXXXXXX/repository/heima-snapshot/</url > </snapshotRepository > </distributionManagement >
执行命令
执行结果