一般情况下,完全没有必要去修改 tomcat 的版本,就算是生产环境使用的 spring boot 内置版本,也是最好使用 spring boot的内置的 tomcat 版本,这是经过兼容测试、回归测试的版本号。可能有的同学会说,生产环境下还不敢冒险去使用最新版的 tomcat,万一出现什么幺蛾子呢?很多公司接受不起生产环境的这种巨大损失,尤其是涉及到金融方面的。所以因循守旧,想要使用经过很多大公司校验的 tomcat 7,甚至是 tomcat 6;当然,不排除这种可能性。比如我司现在生产环境的 tomcat 版本就是7.0.x,而 tomcat 的开发稳定版现在已经到 9.0.6(当前时间:2018年3月14日)。但是另一方面,随着版本的提升,依赖于 tomcat 的良好架构设计,其后续版本的各种性能提升,对于 http 2的支持,难道你真的舍得不去尝试使用吗?
废话说完。
下来详细讲讲怎么修改 tomcat 的版本吧,也是去试着理解一下 tomcat 的启动过程,以及 spring boot 如何内嵌集成 tomcat 的。
想要修改内置的 tomcat 的默认版本,首先得知道当前是什么版本。
比如我当前的 sb 版本是:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>
- 1
- 2
- 3
- 4
- 5
借助于 IDE,查看 spring-boot-starter-tomcat 的 pom 文件:
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</dependency>
</dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
可知所有的 jar。
此时如果是 eclipse 的忠实用户,则可以在当前工程 project 的 maven 依赖里面直接去看 jar 的版本号。
IDEA 则略有不同,IDEA 的 module 概念等于 eclipse 的 project 概念。IDEA 在 External Libraries下面并不能看到版本号信息,尤其是对于多个 module 的工程 project 而言,不同 module 使用不同的 tomcat 版本时如何知道当前 module 使用的是什么版本的 tomcat 呢?
实际上,此时就是要去理解 IDEA 的设计意图咯,我认为 External Libraries 的作用主要是去看源码,debug。在右侧还有一个面板 Maven Projects,找到当前 module,打开 dependencies 信息,然后此时还可以查看 jar 包,即 artifactId 的依赖管理关系:
可知 spring boot 1.5.7 的内置 tomcat 版本是 8.5.20。
方法2:不借助于 IDE 的情况下, 怎么知道版本信息?
打开文件:
/Users/awesome-me/.m2/repository/org/springframework/boot/spring-boot-dependencies/1.5.7.RELEASE/spring-boot-dependencies-1.5.7.RELEASE.pom
可以在标签<properties>
下面找到<tomcat.version>8.5.20</tomcat.version>
下面就尝试修改内置的默认版本。
从上面的方法2,就知道如何修改的思路。
即在 pom.xml 文件里面添加一个标签<properties>
,添加期望的版本<tomcat.version>8.0.30</tomcat.version>
如何知道修改是否成功?
修改成<tomcat.version>8.0.30</tomcat.version>
启动信息:
2018-03-15 00:46:26.275 INFO 47112 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-03-15 00:46:26.282 INFO 47112 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2018-03-15 00:46:26.283 INFO 47112 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.30
2018-03-15 00:46:26.333 INFO 47112 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-03-15 00:46:26.333 INFO 47112 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1000 ms
- 1
- 2
- 3
- 4
- 5
但是,有时候启动会报错:
Caused by: java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory
at org.apache.catalina.util.LifecycleBase.<clinit>(LifecycleBase.java:37)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:169)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134)
... 13 common frames omitted
- 1
- 2
- 3
- 4
- 5
- 6
显然是缺少 jar 包,在 dependency 里面添加即可。
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>${tomcat.version}</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
但是还有另外一个 artifactId
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>${tomcat.version}</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
使用下面这个更好?(待验证)
但是,还有一个问题:
我们知道spring-boot-starter-web
是包含spring-boot-starter-tomcat
的,查看 pom 文件可知:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
- 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
也就是说,我们没有必要重复添加spring-boot-starter-tomcat
,一个spring-boot-starter-web
就可以把一个典型的 spring web 项目搭建成功。也方便了 jar 包的管理。
但是,如果此时你的项目中仅仅添加spring-boot-starter- web
,而没有直接添加spring-boot-starter-tomcat
,就算配置
<properties>
<tomcat.version>9.0.6</tomcat.version>
<!--<tomcat.version>8.0.30</tomcat.version>-->
</properties>
- 1
- 2
- 3
- 4
也并不能生效。至于为什么,有待研究 spring boot 的 autoconfigure 源码才能知道吧。
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-778f64ae39.css" rel="stylesheet">
</div>