【问题标题】:Spring boot WAR deployed to Tomcat ignored code after SpringApplication.run()SpringApplication.run() 之后部署到 Tomcat 的 Spring Boot WAR 忽略了代码
【发布时间】:2020-08-09 13:37:41
【问题描述】:

我正在为我的大学学士论文开发一个网络应用程序。 我遇到了来自 Tomcat 的非常令人不安的行为。尽管我修复了迄今为止在真正的 Tomcat 9.0.34(最新版本 9)和嵌入式 Tomcat 9.0.31 上从“spring-boot-starter-tomcat”依赖项运行 WAR 的所有问题,但这个问题对我来说很神秘。 当 WAR 部署到 Tomcat 服务器时,没有任何代码(我也尝试过 SpringApplication.run(...) 行之后的 System.Out.println(...)logger.info(...)

代码在使用嵌入式 Tomcat 容器运行时执行(例如通过java -jar app.war) 在我的 pom.xml maven 设置中,Tomcat 在“运行时”范围内被标记,因此真实和嵌入式 Tomcat 选项都可用于 WAR。 我的应用程序通过这个 main 运行:

@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 上下文初始化之前为数据库数据播种,因为它会初始化我的服务等。

您知道那里可能出现什么情况吗? 谢谢你的建议!

一月

【问题讨论】:

    标签: java spring-boot maven tomcat runtime


    【解决方案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");
        }
    }
    

    方式二:

    实现 ApplicationRunner..

    @Component
    public class AppRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
          //do after application running
        }
    }
    

    【讨论】:

    • 谢谢!通过构造函数(@Autowired)注入 ApplicationContext 的 ApplicationRunner 就像我需要的那样工作!
    【解决方案2】:

    将您的应用程序部署到 Tomcat 容器时,您的 main 方法不会运行。 Tomcat 有自己的操作系统入口点,您的方法不会被调用。

    SpringBootServletInitializer 有一个可以覆盖的配置方法,但看起来您正试图在应用程序启动之前加载一些数据。我建议将其从应用程序中删除并放入它自己的脚本中,因为您将在每次应用程序启动时初始化该数据。

    【讨论】:

      猜你喜欢
      • 2015-03-10
      • 2018-12-05
      • 2020-06-17
      • 2018-05-18
      • 1970-01-01
      • 2016-08-11
      • 2015-09-03
      • 2016-02-15
      • 2023-01-03
      相关资源
      最近更新 更多