springboot:修改內建tomcat版本
一般情況下,完全沒有必要去修改 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>
一般情況下,完全沒有必要去修改 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>