The closing of SpringBoot applications is currently summarized in four ways.

  1. Rest api: use the spring-boot-starter-actuator module in the ShutdownEndpoint
  2. the exit static method of SpringApplication: just call the static method directly
  3. JMX: use the MXBean provided inside SpringBoot.
  4. use third-party process management tools

Rest api

The Rest api is exposed using Endpoint and requires the introduction of spring-boot-starter-actuator the stater.

The corresponding Endpoint for this shutdown application is ShutdownEndpoint, which directly calls the rest api provided by ShutdownEndpoint. You have to turn on ShutdownEndpoint first (not by default), as well as not to do security monitoring.

1
2
endpoints.shutdown.enabled: true
endpoints.shutdown.sensitive: false

Then request the rest api.

1
curl -X POST http://localhost:8080/shutdown

Security monitoring can be done using spring-security.

1
2
3
4
endpoints.shutdown.sensitive: true
security.user.name: admin
security.user.password: admin
management.security.role: SUPERUSER

Then use the username and password to call.

1
curl -u admin:admin -X POST http://127.0.0.1:8080/shutdown

The underlying ShutdownEndpoint is actually a call to the close method of the Spring container.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
public Map<String, Object> invoke() {

	if (this.context == null) {
		return Collections.<String, Object>singletonMap("message",
				"No context to shutdown.");
	}

	try {
		return Collections.<String, Object>singletonMap("message",
				"Shutting down, bye...");
	}
	finally {

		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(500L);
				}
				catch (InterruptedException ex) {
					// Swallow exception and continue
				}
				ShutdownEndpoint.this.context.close();
			}
		}).start();

	}
}

SpringApplication’s exit static method

SpringApplication provides an exit static method for closing the Spring container, which also has a parameter exitCodeGenerators representing an array of ExitCodeGenerator interfaces. The ExitCodeGenerator interface is a generator that generates the exit code exitCode.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static int exit(ApplicationContext context,
		ExitCodeGenerator... exitCodeGenerators) {
	Assert.notNull(context, "Context must not be null");
	int exitCode = 0; // 默认的退出码是0
	try {
		try {
			// Constructing the ExitCodeGenerator collection
			ExitCodeGenerators generators = new ExitCodeGenerators();
			// Get all beans of type ExitCodeGenerator in the Spring container
			Collection<ExitCodeGenerator> beans = context
					.getBeansOfType(ExitCodeGenerator.class).values();
			// The set plus the ExitCodeGenerator array in the parameters
			generators.addAll(exitCodeGenerators);
			// collection plus the ExitCodeGenerator collection in the Spring container
			generators.addAll(beans);
			// Iterate through each ExitCodeGenerator to get the final exit code exitCode
			// Here each ExitCodeGenerator generates an exit code if it is larger than 0, then take the largest
			// If it is smaller than 0, then take the smallest
			exitCode = generators.getExitCode();
			if (exitCode != 0) { // If the exit code exitCode is not 0, issue an ExitCodeEvent event
				context.publishEvent(new ExitCodeEvent(context, exitCode));
			}
		}
		finally {
			// Closing the Spring Container
			close(context);
		}

	}
	catch (Exception ex) {
		ex.printStackTrace();
		exitCode = (exitCode == 0 ? 1 : exitCode);
	}
	return exitCode;
}

We write a Controller to call the exit method directly.

1
2
3
4
5
6
7
8
9
@Autowired
private ApplicationContext applicationContext;

@PostMapping("/stop")
public String stop() {
		// TODO needs to add permission verification
    SpringApplication.exit(applicationContext);
    return "ok";
}

JMX

spring-boot-starter-actuator This stater internally constructs ShutdownEndpointMBean.

This MBean can be seen using jconsole at

SpringBoot also provides a SpringApplicationAdminMXBean internally, but it needs to be turned on.

1
spring.application.admin.enabled: true

Using third-party process management tools

For example, if our application is deployed on a linux system, we can manage the running of the application with the help of some third-party process management tools, such as supervisor.

Use supervisorctl to access the console to operate the application.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
supervisor> status
stop-application                 STOPPED   Jun 27 03:50 PM
supervisor> start stop-application
stop-application: started
supervisor> status
stop-application                 RUNNING   pid 27918, uptime 0:00:11
supervisor> stop stop-application
stop-application: stopped
supervisor> status
stop-application                 STOPPED   Jun 27 03:50 PM

Reference https://fangjian0423.github.io/2017/06/28/springboot-application-exit/