Solución:
Al usar SpringBoot y Eclipse, puede instalar el complemento de eclipse STS (Spring Tool Suite) para lograr un cierre elegante.
Una vez instalada, ejecute la aplicación como una “Aplicación Spring Boot” en lugar de una “aplicación Java” normal (configuraciones de ejecución / depuración)
Asegúrese de que la casilla de verificación “Habilitar la administración del ciclo de vida” esté marcada y cuando haga clic en el botón cuadrado rojo para detener la aplicación, se realizará un apagado ordenado en lugar de una eliminación total.
Editar:
Vale la pena notar que hay dos “botones cuadrados rojos”. Uno en la barra de herramientas “Iniciar” y otro en el panel “Consola”. El que está en la barra de herramientas de inicio aún realiza una eliminación total, pero el de la consola permite el cierre elegante para la aplicación de arranque por resorte (iniciada con STS)
Después de la investigación, resulta que Eclipse
simplemente termina la aplicación sin ninguna posibilidad de que se ejecute un gancho de cierre.
Encontré una solución / truco gracias a cómo Spring-Boot
está cableado. Cuando se ejecuta el método principal, tomcat se inicia en otro hilo y el método principal continúa ejecutándose hasta su finalización. Esto me permitió insertar un lógica de terminación cuando presiona ‘Enter’.
La aplicación se inicia normalmente y la consola simplemente espera a que se ejecute una tecla Intro. System.exit(1);
:
@SpringBootApplication
@EnableRedisRepositories
public class Launcher {
public static void main(String[] args){
new SpringApplicationBuilder() //
.sources(Launcher.class)//
.run(args);
System.out.println("Press 'Enter' to terminate");
new Scanner(System.in).nextLine();
System.out.println("Exiting");
System.exit(1);
}
}
Al iniciar la aplicación desde Eclipse, en lugar de cerrar la aplicación desde la interfaz, ahora presiono enter en la consola. Ahora, los ganchos de cierre (@PreDestroy
) se activa y el servidor Redis se detiene.
No es lo que esperaba, pero al menos por el momento, Embedded Redis Server está detenido con la aplicación y no tengo que seguir matándolo manualmente.
ExitCodeGenerator
requiere que la aplicación llame al exit
método
System.exit(SpringApplication
.exit(SpringApplication.run(SampleBatchApplication.class, args)));
También puede registrar un gancho de cierre. Se llamarán ganchos
- cuando la VM se termina normalmente (
System.exit
). - en respuesta a una interrupción
Ctrl+C
,SIGINT
) o señal (SIGHUP
,SIGTERM
).
En algunas circunstancias, si la máquina virtual no se apaga limpiamente (SIGKILL
, errores internos de la máquina virtual, errores en los métodos nativos), no hay garantía de que se llamen o no a los hooks de cierre.
El código para tu EmbeddedRedis
El componente podría verse así:
@PostConstruct
public void startRedis() throws IOException {
redisServer = new RedisServer(redisPort);
redisServer.start();
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
redisServer.stop();
}
});
}