前言
写本文的目的
文章书写时我正在通过Bilibili黑马程序员的SSM视频学习SpringMVC,旨在记录自身在学习过程中出现的问题。
正文
##问题描述
在跟着视频学习 SpringMVC,跟着视频敲完入门案例时出现tomcat容器无法启动问题,花时间研究后是jdk、springMVC框架、tomcat版本问题。
视频传送门:SpringMVC-02-SpringMVC入门案例_哔哩哔哩_bilibili
笔者运行环境
jdk20,maven 3.8.8, tomcat10
问题复现
我的代码是按照视频中编写的,流程大致如下
-
项目结构
-
pom.xml
视频中导入了javax包下的servlet依赖项、springMVC配置包、tomcat7的插件
-
controller包
- userController.java
- userController.java
-
config包
-
SpringMvcConfig.java
-
ServletContainerInitConfig.java
-
-
视频中的运行结果
我跟着做的运行结果
此时我的 MVC框架版本是6.1.6,更换成视频中的5.2.10.RELEASE 版本,结果就是可以正常启动容器,但是会爆出各种异常
图中显示的异常为 BeanDefinitionStoreException ,这个异常表示Spring在加载Bean时出现了问题,案例中的原因主要是jdk版本和spring框架版本不匹配。
分析原因
JDK 和 SpringMVC框架 以及 Tomcat版本不匹配的原因
JDK和Spring的版本关系以及SpringMVC与Servlet规范的关系
我的 JDK版本为20,应该使用6.0以上的Spring框架,版本不匹配是当前出现 BeanDefinitionStoreException
的主要原因
SpringMVC 在编写Servlet容器用于配置的抽象类AbstractDispatcherServletInitializer
需要依赖Servlet的API,这也是为什么要导入Servlet-API
这个包的原因。需要注意的是SpringMVC 6.0 以下的版本用的是Servlet3.0
规范,而6.0 以上的版本使用的则是Servlet4.0
以上的规范,两个版本主要区别是 3.0位于 javax.servlet
包下,而 4.0 以上位于jakarta.servlet
包下
SpringMVC 5.2.10.RELEASE 使用Servlet3.0规范制作的接口
SpringMVC 6.1.6 使用Servlet4.0 规范制作的接口
而这也是Tomcat不能正常启动的主要原因
Servlet规范与Tomcat的关系
Tomcat10 使用了 Servlet5.0的规范,所以其在启动时需要寻找位于Jakarta包下的ServletAPI
而10 以前的版本使用的都是3.0及以下的规范,其在启动时需要寻找位于Javax包下的SerletAPI
解决方法
-
使用本地的Tomcat10 容器运行项目
-
修改servletAPI坐标
-
配置本地tomcat10
-
配置tomcat10工件
-
直接运行tomcat,启动成功
-
-
maven中导入tomcat10的插件
根据文档最新的插件版本为2.3,最高支持tomcat7,没有10
-
将JDK版本降至JDK8再写(不尝试了)