【SpringBoot/Themeleaf】spring-boot-starter-tomcat的scope配置成provided导致程序跑不起来
有一个使用Themeleaf模板引擎的Springboot程序,装配完毕后总是跑不起来,控制台里总是报:
2022-03-24 10:29:47.196 - Started MyApplication in 3.783 seconds (JVM running for 5.625) 2022-03-24 10:29:47.212 - HikariPool-1 - Shutdown initiated... 2022-03-24 10:29:47.446 - HikariPool-1 - Shutdown completed.
出现此消息后,看idea右上角显示程序运行中的方块没有点亮,是灰色而不是红色;然后在浏览器里敲localhost:8080/dmo(dmo是我app的context)也显示“无法访问此网站,localhost 拒绝了我们的连接请求。”
当时还没意识到是pom.xml里出了问题,于是一路检查mybatis设置等,发现都没问题才回到溯源到pom。
在网文的提示下,找到了这里:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
再去查scope定义成provided是什么意思,原来provided只能作用在编译和测试时,这还运行得起来?
于是将provided改成了默认的compile,就是这样:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>compile</scope> </dependency>
然后刷新maven,clean,在启动MyApplication,控制台里报出了熟悉的话语:
2022-03-24 10:27:54.806 - Starting ProtocolHandler ["http-nio-8080"] 2022-03-24 10:27:54.853 - Tomcat started on port(s): 8080 (http) with context path '/dmo' 2022-03-24 10:27:54.869 - Started MyApplication in 4.977 seconds (JVM running for 7.002)
再看小方块变成红色,访问localhost:8080/dmo也如预期了。
之后再试了几次,确认问题就出在providid处,改成默认的compile就好,此外也可以把scope一行删除,因为不写scope默认的就是compile。
此外还需要注意的是,eclipse/sts里一般是默认自动编译,idea里需要手动clean,如果改动xml等配置文件更是要如此。如果没有手动clean/compile这一下,修改完了没编译出来,就是改对了也跑不起来,这是idea做得不好的一点。
附录:scope的意义:
scope取值 | 有效范围(compile, runtime, test) | 依赖传递 | 例子 |
---|---|---|---|
compile | all | 是 | spring-core |
provided | compile, test | 否 | servlet-api |
runtime | runtime, test | 是 | JDBC驱动 |
test | test | 否 | JUnit |
system | compile, test | 是 |
正如上表所示,
compile :为默认的依赖有效范围。如果在定义依赖关系的时候,没有明确指定依赖有效范围的话,则默认采用该依赖有效范围。此种依赖,在编译、运行、测试时均有效。
provided :在编译、测试时有效,但是在运行时无效。例如:servlet-api,运行项目时,容器已经提供,就不需要Maven重复地引入一遍了。
runtime :在运行、测试时有效,但是在编译代码时无效。例如:JDBC驱动实现,项目代码编译只需要JDK提供的JDBC接口,只有在测试或运行项目时才需要实现上述接口的具体JDBC驱动。
test :只在测试时有效,例如:JUnit。
system :在编译、测试时有效,但是在运行时无效。和provided的区别是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量。
参考资料:
https://www.cnblogs.com/makai/p/12294449.html