Spring 에서 Exit Code 활용하기 (How to handle exit code in Spring Framework)
들어가며
Spring Framework 를 이용하여 프로젝트를 최초 생성하고 나서, 처음 실행을 하면 마지막에 다음과 같이 표기됩니다. Exit Code 가 보이게 되죠.. (최초 생성시에는 Controller 등 listen 하고 있는 객체 생성을 하지 않아 실행과 동시에 종료됩니다..)
여기서는 이 코드값의 의미에 대해서 알아보고, Exit Code를 customizing 해서 원하는 기능을 구현할 수 있는지를 검토해 보고자 합니다.
Exit Code 가지고 놀기
모든 프로그램은 종료 시점에 정수형 exit code를 return 합니다. Spring Boot 는 Exception 이 발생한 경우 Exit Code를 1로 return 하고 종료됩니다. 그렇지 않고 정상적인 종료가 이루어진 경우(clean exit)에는 0을 return 합니다.
Spring 은 shutdown hooks 를 등록합니다. 또한 org.springframework.boot.ExitCodeGenerator 라는 인터페이스도 제공하는데, 이 인터페이스가 System.exit() 가 호출되는 시점에 특정한 code를 리턴하게 합니다.
ExitCodeGenerator
ExitCodeGenerator 의 구현체가 되는 class를 만들어 보겠습니다. 여기서는 getExitCode() 라는 함수를 override해서 정수값을 return 하도록 합니다.
@SpringBootApplication
public class DemoApplication implements ExitCodeGenerator {
public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(DemoApplication.class, args)));
}
@Override
public int getExitCode() {
return 42;
}
}
ExitCodeExceptionMapper
이제 RuntimeException 기반으로 exit code를 구성하는 방법에 대해서 살펴보겠습니다. 이를 위해서 CommandLinerunner 를 구현하겠습니다. commandLineRunner 는 항상 NumberFormatException을 발생시키고, ExitCodeExceptionMapper Bean 을 등록합니다.
@Bean
CommandLineRunner createException() {
return args -> Integer.parseInt("test") ;
}
@Bean
ExitCodeExceptionMapper exitCodeToexceptionMapper() {
return exception -> {
// set exit code base on the exception type
if (exception.getCause() instanceof NumberFormatException) {
return 80;
}
return 1;
};
}
ExitCodeEvent
다음으로, ExitCodeEvent 를 capture 합니다. 이를 위해서 ExitCodeEvnets 를 subscribe 하는 event listener를 등록합니다.
@Bean
DemoListener demoListenerBean() {
return new DemoListener();
}
private static class DemoListener {
@EventListener
public void exitEvent(ExitCodeEvent event) {
System.out.println("Exit code: " + event.getExitCode());
}
}
이제, 어플리케이션이 종료될 때, exitEvent() 함수가 실행되고, 여기서 event 의 exitCode를 읽어서 처리해 주면 됩니다.