今天在将已经开发好的 SpringBoot 项目转换成 war 项目,然后在 tomcat 中运行。但是,在启动 tomcat 时一切都正常,能正常访问项目;遗憾的是,看 tomcat 输出的日志发现 SpringBoot 加载了两次。即看见两次输出 banner 信息。
为了这个问题在网上看了很多解决办法,主要的解决办法是将 tomcat 的依赖删除调。pom.xml 如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 移除嵌入式tomcat插件 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
我按照上面的解决办法,还是会加载两次。
还是自己折腾了很久,才定位到 configure() 方法。该方法从 SpringBootServletInitializer 类继承而来,方法的定义如下:
/**
* Configure the application. Normally all you would need to do is to add sources
* (e.g. config classes) because other settings have sensible defaults. You might
* choose (for instance) to add default command line arguments, or set an active
* Spring profile.
* @param builder a builder for the application context
* @return the application builder
* @see SpringApplicationBuilder
*/
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder;
}
配置应用程序。通常你所需要做的就是添加源(例如配置类),因为其他设置有合理的默认值。您可以选择(例如)添加默认的命令行参数,或者设置活动的Spring配置文件。
如果我们需要使用 tomcat 启动应用,需要重写 configure 方法。如下:
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// tomcat 启动需要配置
// 注意这里要指向原先用main方法执行的Application启动类
return builder.sources(AppServerApplication.class);
}
此时,回到我们的问题上面,导致 tomcat 加载两次 SpringBoot 项目两次有如下原因:
项目中有两个类继承了 SpringBootServletInitializer 类,一个为 AppServerApplication(有 main 方法的类),另一个是为了在 tomcat 启动项目而创建的 SpringBootStartApplication 该类重写了 configure 方法。
解决办法:
将 SpringBootStartApplication 类删除,即保证我们只有一个类继承 SpringBootServletInitializer 类即可。