= ``ExitCodeGenerator``에 관한 이야기 honeymon, v0.0.1, 2018/03/12 :sb: 스프링 부트 :app: 애플리케이션 * link:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exit[Application Exit - Spring Boot Reference Guide] {app}이 정상적으로 종료되는 것은 꽤 중요하다. {app}의 갑작스런 죽음과는 달리 특정 상황이 발생했고 그 상황에 맞춰 종료코드를 반환하고 죽는다면 그에 대한 대응하기가 수월해진다. {sb}에서 장애대응을 수월하게 할 수 있도록 특정상황에 따른 종료코드(Exit Code)를 반환하며 {app}을 정상종료 시키는 기능을 제공한다. {sb} 참고문서에 나온 예제는 다음과 같다. [source,java] ---- @SpringBootApplication public class ExitCodeApplication { @Bean public ExitCodeGenerator exitCodeGenerator() { return () -> 42; } public static void main(String[] args) { System.exit(SpringApplication .exit(SpringApplication.run(ExitCodeApplication.class, args))); } } ---- 이와 관련된 것은 아래 두 가지다. * ``ExitCodeGenerator`` * ``SpringApplication.exit(ApplicationContext context, ExitCodeGenerator... exitCodeGenerators)`` 위 코드는 대략 다음과 같다. .``ExitCodeGenerator`` [source,java] ---- @FunctionalInterface public interface ExitCodeGenerator { /** * Returns the exit code that should be returned from the application. * @return the exit code. */ int getExitCode(); } ---- .``SpringApplication.exit()`` 메서드 [source,java] ---- public static int exit(ApplicationContext context, ExitCodeGenerator... exitCodeGenerators) { Assert.notNull(context, "Context must not be null"); int exitCode = 0; try { try { ExitCodeGenerators generators = new ExitCodeGenerators(); Collection beans = context .getBeansOfType(ExitCodeGenerator.class).values(); generators.addAll(exitCodeGenerators); generators.addAll(beans); exitCode = generators.getExitCode(); if (exitCode != 0) { // <1> context.publishEvent(new ExitCodeEvent(context, exitCode)); } } finally { close(context); } } catch (Exception ex) { ex.printStackTrace(); exitCode = (exitCode == 0 ? 1 : exitCode); } return exitCode; } ---- <1> ``exitCode != 0`` 조건이 만족하면 ``ExitCodeEvent`` 이벤트가 발생한다. ``ExitCodeGenerator`` 인터페이스를 ``SpringApplication.exit()`` 전달하면 ``SpringApplication.exit()``는 ``getExitCode()`` 메서드를 호출하여 종료코드를 받는다. 이 때 이 종료코드가 0인 경우에는 일반적인 애플리케이션 종료를 진행한다. [NOTE] ==== ``0``이 아닌 경우에는 종료코드 발송 이벤트(``ExitCodeEvent``)가 발생한 후 애플리케이션이 종료된다. ==== 애플리케이션에서 특정 예외발생 시 다음과 같은 형식으로 종료코드 반환 이벤트를 발생시키며 종료시킬 수 있겠다. [source,java] ---- @Autowired ExitCodeGenerator exitCodeGenerator; try { // 예외가 발생할 수 있는 상황 } catch (WannabeException e) { // 특정조건의 예외가 발생하면 애플리케이션을 안전하게 종료시킬 수도 있겠다. // SpringApplication.exit(applicationContext, exitCodeGenerator); } ---- ``WannabeException``에 대한 예외처리를 할 수 있는 ``@ControllerAdvice`` 클래스를 정의해서 ``WannabeException``가 발생하면 특정코드를 발생하며 종료되도록 하는 것도 가능하겠다. [source,java] ---- @ControllerAdvice class GlobalControllerExceptionHandler { @ExceptionHandler(WannabeException.class) public void handleConflict(WannabeException we) { // todo we SpringApplication.exit(applicationContext, () -> 810301); } } ----