以编程方式关闭Spring引导应用程序

时间:2022-08-22 13:42:45

How can I programmatically shutdown a Spring Boot application without terminating the VM?

如何在不终止VM的情况下以编程方式关闭Spring引导应用程序?

In other works, what is the opposite of

在其他作品中,什么是相反的

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

4 个解决方案

#1


60  

Closing a SpringApplication basically means closing the underlying ApplicationContext. The SpringApplication#run(String...) method gives you that ApplicationContext as a ConfigurableApplicationContext. You can then close() it yourself. For example,

关闭SpringApplication基本上意味着关闭底层的ApplicationContext。SpringApplication#run(String…)方法将ApplicationContext作为一个可配置的ApplicationContext。然后您可以自己关闭它。例如,

@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();
    }
}

Alternatively, you can use the static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...) helper method to do it for you. For example,

或者,您可以使用静态SpringApplication。退出(ApplicationContext, ExitCodeGenerator…)helper方法为您执行。例如,

@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);
    }
}

#2


28  

In a spring boot application you can use something like this

在spring引导应用程序中,您可以使用类似的方法。

ShutdownManager.java

ShutdownManager.java

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

class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

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

#3


25  

This works, even done is printed.

这个作品,即使完成了也会被打印出来。

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

So adding .close() after run()

所以在run()之后添加。close()

Explanation:

解释:

public ConfigurableApplicationContext run(String... args)

公共ConfigurableApplicationContext运行(字符串…args)

Run the Spring application, creating and refreshing a new ApplicationContext. Parameters:

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

args - the application arguments (usually passed from a Java main method)

args——应用程序参数(通常来自Java main方法)

Returns: a running ApplicationContext

返回:ApplicationContext运行

and:

和:

void close() Close this application context, releasing all resources and locks that the implementation might hold. This includes destroying all cached singleton beans. Note: Does not invoke close on a parent context; parent contexts have their own, independent lifecycle.

void close()关闭这个应用程序上下文,释放实现可能包含的所有资源和锁。这包括销毁所有缓存的单例bean。注意:在父上下文中不调用close;父上下文有它们自己的独立的生命周期。

This method can be called multiple times without side effects: Subsequent close calls on an already closed context will be ignored.

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

So basically, it will not close tha parent context, that's why the VM doesn't quit.

所以基本上,它不会关闭父上下文,这就是为什么VM不退出。

#4


1  

In the application you can use SpringApplication. This has a static exit() method that takes two arguments: the ApplicationContext and an ExitCodeGenerator:

在应用程序中,您可以使用SpringApplication。它有一个静态exit()方法,它接受两个参数:ApplicationContext和ExitCodeGenerator:

i.e. you can declare this method:

即你可以声明此方法:

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

Inside the Integration tests you can achieved it by adding @DirtiesContext annotation at class level:

在集成测试中,可以通过在类级添加@DirtiesContext注释来实现:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - The associated ApplicationContext will be marked as dirty after the test class.
  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) -在测试类之后,关联的ApplicationContext将被标记为dirty。
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - The associated ApplicationContext will be marked as dirty after each test method in the class.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)——在类中的每个测试方法之后,关联的ApplicationContext将被标记为dirty。

i.e.

即。

@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 {
...

#1


60  

Closing a SpringApplication basically means closing the underlying ApplicationContext. The SpringApplication#run(String...) method gives you that ApplicationContext as a ConfigurableApplicationContext. You can then close() it yourself. For example,

关闭SpringApplication基本上意味着关闭底层的ApplicationContext。SpringApplication#run(String…)方法将ApplicationContext作为一个可配置的ApplicationContext。然后您可以自己关闭它。例如,

@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();
    }
}

Alternatively, you can use the static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...) helper method to do it for you. For example,

或者,您可以使用静态SpringApplication。退出(ApplicationContext, ExitCodeGenerator…)helper方法为您执行。例如,

@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);
    }
}

#2


28  

In a spring boot application you can use something like this

在spring引导应用程序中,您可以使用类似的方法。

ShutdownManager.java

ShutdownManager.java

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

class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

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

#3


25  

This works, even done is printed.

这个作品,即使完成了也会被打印出来。

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

So adding .close() after run()

所以在run()之后添加。close()

Explanation:

解释:

public ConfigurableApplicationContext run(String... args)

公共ConfigurableApplicationContext运行(字符串…args)

Run the Spring application, creating and refreshing a new ApplicationContext. Parameters:

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

args - the application arguments (usually passed from a Java main method)

args——应用程序参数(通常来自Java main方法)

Returns: a running ApplicationContext

返回:ApplicationContext运行

and:

和:

void close() Close this application context, releasing all resources and locks that the implementation might hold. This includes destroying all cached singleton beans. Note: Does not invoke close on a parent context; parent contexts have their own, independent lifecycle.

void close()关闭这个应用程序上下文,释放实现可能包含的所有资源和锁。这包括销毁所有缓存的单例bean。注意:在父上下文中不调用close;父上下文有它们自己的独立的生命周期。

This method can be called multiple times without side effects: Subsequent close calls on an already closed context will be ignored.

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

So basically, it will not close tha parent context, that's why the VM doesn't quit.

所以基本上,它不会关闭父上下文,这就是为什么VM不退出。

#4


1  

In the application you can use SpringApplication. This has a static exit() method that takes two arguments: the ApplicationContext and an ExitCodeGenerator:

在应用程序中,您可以使用SpringApplication。它有一个静态exit()方法,它接受两个参数:ApplicationContext和ExitCodeGenerator:

i.e. you can declare this method:

即你可以声明此方法:

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

Inside the Integration tests you can achieved it by adding @DirtiesContext annotation at class level:

在集成测试中,可以通过在类级添加@DirtiesContext注释来实现:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - The associated ApplicationContext will be marked as dirty after the test class.
  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) -在测试类之后,关联的ApplicationContext将被标记为dirty。
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - The associated ApplicationContext will be marked as dirty after each test method in the class.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)——在类中的每个测试方法之后,关联的ApplicationContext将被标记为dirty。

i.e.

即。

@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 {
...