Java SpringBootWar部署到Tomcat忽略了SpringApplication.run()之后的代码
我正在为我的大学学士学位论文开发一个web应用程序。 我正在经历一个来自Tomcat的非常令人不安的行为。虽然我修复了所有在真正的Tomcat 9.0.34(最新版本9)上运行WAR与在嵌入式Tomcat 9.0.31上运行WAR的问题,但这个问题对我来说是神秘的。 当WAR部署到Tomcat服务器时,在Java SpringBootWar部署到Tomcat忽略了SpringApplication.run()之后的代码,java,spring-boot,maven,tomcat,runtime,Java,Spring Boot,Maven,Tomcat,Runtime,我正在为我的大学学士学位论文开发一个web应用程序。 我正在经历一个来自Tomcat的非常令人不安的行为。虽然我修复了所有在真正的Tomcat 9.0.34(最新版本9)上运行WAR与在嵌入式Tomcat 9.0.31上运行WAR的问题,但这个问题对我来说是神秘的。 当WAR部署到Tomcat服务器时,在SpringApplication.run(…)行之后的所有代码(我也尝试了System.Out.println(…)或logger.info(…))都不会执行 但是,当使用嵌入式Tomcat容
SpringApplication.run(…)
行之后的所有代码(我也尝试了System.Out.println(…)
或logger.info(…)
)都不会执行
但是,当使用嵌入式Tomcat容器(例如通过java-jar app.war
)运行时,代码会执行
在我的pom.xmlmaven设置中,Tomcat在作用域中被标记为“runtime”,因此实体和嵌入式Tomcat选项都可用于WAR。
我的应用程序通过以下主要路径运行:
@SpringBootApplication
@ComponentScan(basePackages={"com.me.myProject"})
@ServletComponentScan
public class MySpringWebApplication extends SpringBootServletInitializer /* needed for WAR packaging */ {
...public static void main(String[] args){
ApplicationContext ctx = SpringApplication.run(MySpringWebApplication.class, args);
DatabaseSeeder sampleDataSeeder = new DatabaseSeeder(ctx.getBean(UserDAO.class), ctx.getBean(RegisterService.class), ctx.getBean(LibraryDAO.class));
sampleDataSeeder.ensureSampleLibraryExistence(); //this code is not executed in real Tomcat
sampleDataSeeder.ensureSampleLibraryExistence(); //this code isn't either
sampleDataSeeder.ensureSampleLibraryExistence(); //I spammed more of this to checkthat it really didn't happen
sampleDataSeeder.ensureSampleLibraryExistence();
sampleDataSeeder.ensureSampleLibraryExistence();
sampleDataSeeder.ensureSampleLibraryExistence();
EmailService service = ctx.getBean(EmailService.class);
service.sendEmailToMaintainer("end of main reached", "some text"); //this email is never sent on real Tomcat but always sent on embedded Tomcat
}}
在初始化spring上下文之前,我无法为数据库数据设定种子,因为它会初始化我的服务等
你知道那里可能是什么情况吗?
谢谢你的建议
Jan将应用程序部署到Tomcat容器时,您的主方法没有运行。Tomcat有自己的操作系统入口点,您的方法不会被调用
SpringBootServletInitializer有一个可以重写的配置方法,但它看起来像是在应用程序启动前加载一些数据。我建议您将其从应用程序中删除,并放入自己的脚本中,因为每次应用程序启动时,您都将初始化该数据。如果您想在应用程序启动后执行某些操作,请应用程序运行…有两种方法可以做到这一点: 方式1: 实现CommandLineRunner和实现run方法
@SpringBootApplication
@ComponentScan(basePackages={"com.me.myProject"})
@ServletComponentScan
public class MySpringWebApplication extends SpringBootServletInitializer implements CommandLineRunner /* needed for WAR packaging */ {
public static void main(String[] args){
ApplicationContext ctx = SpringApplication.run(MySpringWebApplication.class, args);
//this email is never sent on real Tomcat but always sent on embedded Tomcat
}
@Override
public void run(String... args) throws Exception {
DatabaseSeeder sampleDataSeeder = new DatabaseSeeder(ctx.getBean(UserDAO.class), ctx.getBean(RegisterService.class), ctx.getBean(LibraryDAO.class));
sampleDataSeeder.ensureSampleLibraryExistence(); //this code is not executed in real Tomcat
sampleDataSeeder.ensureSampleLibraryExistence(); //this code isn't either
sampleDataSeeder.ensureSampleLibraryExistence(); //I spammed more of this to checkthat it really didn't happen
sampleDataSeeder.ensureSampleLibraryExistence();
sampleDataSeeder.ensureSampleLibraryExistence();
sampleDataSeeder.ensureSampleLibraryExistence();
EmailService service = ctx.getBean(EmailService.class);
service.sendEmailToMaintainer("end of main reached", "some text");
}
}
方式2:
实现ApplicationRunner
@Component
public class AppRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
//do after application running
}
}
谢谢!通过构造函数(@Autowired)注入ApplicationContext的ApplicationRunner可以按照我的需要工作!