第2章 Maven依赖管理
为了更加方便地使用Maven,我们在idea中使用Maven
2.1 用idea创建Maven Web项目
1. 创建Maven项目,勾中Create from archetype,然后指定一个插件&目标,然后点击Next
2. 填写项目坐标:GAV,然后点击Next下一步
3. 选择当前项目使用的Maven、Maven的配置、Maven的本地仓库的位置,然后点击Finish完成
4. idea会自动生成Maven默认插件的配置,其实删掉这些配置,也仍然会使用这些默认插件的
<?xml versinotallow="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:schemaLocatinotallow="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.gao</groupId>
<artifactId>web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.2 idea集成Tomcat
1. 点击界面右上角的“Add Configuration”
2. 点击左上角的“+”
3. 选择Tomcat Server下的Local
4. 点击Configure,配置好Tomat,然后点击Apply,然后点击OK
5. 此时我们会看到右上角的tomcat9上有个红叉,这是因为tomact中没有部署任何web应用,所以有这么一个红叉
6. 点击Edit Configurations
7. 点击右下角的“Fix”
8. 点击Artifact
9. 随便选一个,都能部署,web:war是把当前应用打成war包再部署,web:war:exploded是把当前应用直接以文件夹的形式部署到tomcat9
10. 修改web应用发布出去的名字,然后点击Apply、OK
11. 在项目中引入servlet依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
12. 编写Servlet
@WebServlet("/foo.do")
public class FooServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("Hello Maven Servlet!");
}
}
13. 启动tomcat,发现控制台有乱码
14. 打开tomcat目录下的conf目录下的logging.properties文件,在最后一行加上以下配置:
15. 再次重启tomcat,中文已经正常
16. 访问
17. idea默认不会把项目发布到你自己指定的tomcat的webapps下,如果要指定应用的部署位置,可以按如下步骤来做
2.3 依赖范围
依赖范围 | 编译阶段 | 测试阶段 | 运行时 | 示例 |
compile(默认值) | T | T | T | log4j |
test | F | T | F | junit |
provided | T | T | F | servlet-api |
runtime | F | T | T | jdbc |
2.4 依赖传递
如果B依赖了C,则当A依赖于B时,也会自动引入C。也就是 A --> B --> C,比如我们在项目中引入了spring-context依赖,而该依赖又依赖于其他多个依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
2.5 依赖冲突
如果B依赖于X(1.1)版本,C依赖于X(1.2)版本,
B --> X(1.1)
C --> X(1.2)
此时如果A同时引入B和C,那么到底会是以下哪种情况?
A --> X(1.1)
A --> X(1.2)
在Maven中,有两个解决依赖冲突的原则:
1. 第一声明者优先
2. 路径近者优先
我们以以下两个依赖为例来演示Maven是如何解决依赖冲突的
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.16.RELEASE</version>
</dependency>
spring-context和spring-webmvc都依赖于spring-beans,但是版本不一样
此时是第一声明者优先,所以优先使用spring-beans:5.3.13版本
而如果我们直接手动引入spring-beans依赖,则优先使用手动引入的这个版本,这便是路径近者优先
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.20.RELEASE</version>
</dependency>
注意,虽然spring-beans 5.0.20引入在最下方,但仍然优先使用该版本:
2.6 手动解决依赖冲突
2.6.1 排除依赖
之前关于依赖冲突的解决方式是由maven自己解决的,我们还可以自己手动解决依赖冲突
2.6.2 版本锁定
可以锁定spring-beans的版本,如下:
2.7 依赖范围传递性
知道有这么个东西就行了,别去尝试记忆,需要的时候查阅此表即可