ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SpringApplicationRunner란? (+ 동작과정)
    Spring Framework 2023. 9. 8. 00:01

    개요

    Spring Boot를 실행했을 때 매번 특정 코드를 호출하는 방법에 대해 알아보다가 알게 된 Spring ApplicationRunner에 대해서 알아보고자 합니다.

     

     

    ApplicationRunner

    @FunctionalInterface
    public interface ApplicationRunner {
    
    	/**
    	 * Callback used to run the bean.
    	 * @param args incoming application arguments
    	 * @throws Exception on error
    	 */
    	void run(ApplicationArguments args) throws Exception;
    
    }

     

    Bean이 SpringApplication 내에 포함될 때 실행되어야 함을 나타내는 데 사용되는 인터페이스입니다.

    동일한 애플리케이션 내에서 여러 ApplicationRunner 빈을 정의해서 사용할 수 있으며 @Order 어노테이션을 사용하여 순서를 지정할 수 있습니다.

     

    ApplicationRunner 활용해보기

    @Component
    @Order(1)
    class FirstApplicationRunner(): ApplicationRunner{
    	override fun run(args: ApplicationArguments?) {
    		println("first")
    	}
    }
    
    @Component
    @Order(2)
    class SecondApplicationRunner(): ApplicationRunner{
    	override fun run(args: ApplicationArguments?) {
    		println("second")
    	}
    }
    
    //결과
    first
    second

    @Component를 활용해 빈으로 등록하고 @Order를 활용하여 순서를 지정하여 Spring Boot가 기동 될 때 정해진 코드를 실행할 수 있습니다.

     

    ApplicationRunner의 동작과정

    SpringApplication 클래스

    public ConfigurableApplicationContext run(String... args) {
    	... 중략
        callRunners(context, applicationArguments);
    }

     SpringApplication 클래스의 run 메서드 내부에서 callRunners를 호출합니다.

     

    callRunner 메서드

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
    		List<Object> runners = new ArrayList<>();
    		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    		AnnotationAwareOrderComparator.sort(runners);
    		for (Object runner : new LinkedHashSet<>(runners)) {
    			if (runner instanceof ApplicationRunner applicationRunner) {
    				callRunner(applicationRunner, args);
    			}
    			if (runner instanceof CommandLineRunner commandLineRunner) {
    				callRunner(commandLineRunner, args);
    			}
    		}
    	}

     

    callRunners 메서드를 보면 ApplicationRunner 클래스를 conext에서 가져와 runners List에 추가합니다.

    이후 반복문을 통하여 callRunner 메서드를 호출합니다.

     

    callRunner 메서드

    private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
    		try {
    			(runner).run(args);
    		}
    		catch (Exception ex) {
    			throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
    		}
    	}

    callRunner 메서드에서는 실제로 ApplicationRunner 인터페이스를 호출하여 run 메서드를 실행시킵니다.

    만약 예외가 발생하는 경우에는 Failed to execute ApplicationRunner 메시지와 함께 IllegalStateException을 반환합니다.

    댓글

Designed by Tistory.