以编程方式关闭Spring Boot应用程序

时间:2014-04-08 17:27:56

标签: java spring spring-boot

如何以编程方式关闭 Spring Boot 应用而不终止VM

在其他作品中,与

相反
new SpringApplication(Main.class).run(args);

5 个答案:

答案 0 :(得分:83)

关闭SpringApplication基本上意味着关闭基础ApplicationContextSpringApplication#run(String...)方法会将ApplicationContext视为ConfigurableApplicationContext。然后你可以自己close()。例如,

@SpringBootApplication
public class Example {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
        // ...determine it's time to shut down...
        ctx.close();
    }
}

或者,您可以使用static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)帮助程序方法为您执行此操作。例如,

@SpringBootApplication
public class Example {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
        // ...determine it's time to stop...
        int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
            @Override
            public int getExitCode() {
                // no errors
                return 0;
            }
        });
        System.exit(exitCode);
    }
}

答案 1 :(得分:44)

在Spring启动应用程序中,您可以使用类似这样的内容

<强> ShutdownManager.java

import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;

@Component
class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

    public void initiateShutdown(int returnCode){
        SpringApplication.exit(appContext, () -> returnCode);
    }
}

答案 2 :(得分:27)

这项工作,甚至已完成印刷。

  SpringApplication.run(MyApplication.class, args).close();
  System.out.println("done");

所以在.close()

之后添加run()

说明:

  

public ConfigurableApplicationContext run(String... args)

     

运行Spring应用程序,创建并刷新新应用程序   ApplicationContext中。参数:

     

args - 应用程序参数(通常从Java main传递   方法)

     

返回:   正在运行的ApplicationContext

  

void close()关闭此应用程序上下文,释放所有资源   并锁定实现可能包含的内容。这包括摧毁   所有缓存的单例bean。注意:不会在父级上调用close   上下文;父语境有自己独立的生命周期。

     

此方法可以多次调用,没有副作用:   对已经关闭的上下文的后续关闭调用将被忽略。

基本上,它不会关闭父上下文,这就是VM不退出的原因。

答案 3 :(得分:2)

在应用中,您可以使用SpringApplication。这有一个静态exit()方法,它有两个参数:ApplicationContextExitCodeGenerator

即。你可以声明这个方法:

@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
    SpringApplication.exit(applicationContext, exitCodeGenerator);
}

在集成测试中,您可以通过在课程级别添加@DirtiesContext注释来实现它:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - 在测试类之后,关联的ApplicationContext将被标记为脏。
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - 在类中的每个测试方法之后,关联的ApplicationContext将被标记为脏。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Application.class},
    webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port:0"})
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS)
public class ApplicationIT {
...

答案 4 :(得分:0)

这将确保SpringBoot应用程序已正确关闭,并且资源已释放到操作系统中,

@Autowired
private ApplicationContext context;

@GetMapping("/shutdown-app")
public void shutdownApp() {

    int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
    System.exit(exitCode);
}