이번 포스팅에서는 Spring Boot
Appliacation 실행시 자동으로 특정 작업을 실행하는 방법에 대해 설명하도록 하겠습니다.
스프링 부트에서는 애플리케이션 구동 시점에 특정 코드를 실행시키기 위해서 2가지 인터페이스
를 제공하고 있습니다.
CommandLineRunner
: 스트링 타입의 인자를 파라미터로 받아서 사용ApplicationRunner
: 다양한 종류의 파라미터를 받아서 실행하는 경우에 사용CommandLineRunner
는 스프링 부트 1.0
에 추가된 함수형 인터페이스로써 스프링 애플리케이션이 구동된 후에 실행되어야하는 빈을 정의하기 위해 사용됩니다.
아래 코드는 Spring Boot 에서 제공하는 인터페이스 명세입니다.
package org.springframework.boot;
@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
CommandLineRunner
는 파라미터로 String 타입의 가변 인자를 받고 있으며, 인터페이스 이름 그대로 커맨드 라인으로 받은 스트링 타입의 인자를 파라미터로 받아서 사용하기 위해 만들어졌습니다.
CommandLineRunner
는 이를 구현하는 클래스를 정의하고 빈으로 등록하면 애플리케이션이 구동된 후에 자동으로 run() 메소드가 실행됩니다.
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class InitRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
log.info("CommandLineRunner Args: {}", Arrays.toString(args));
}
}
터미널(Terminal)에서 아래와 같이 명령어를 입력하면 애플리케이션을 실행할 수 있습니다.
$java -jar sample-0.0.1.jar abc 123
InitRunner 클래스의 run() 메소드의 인자로 넘어와서 출력됩니다.
TomcatWebServer : Tomcat started on port(s): 443 (https) with context path ''
TestRunner : CommandLineRunner Args: [abc, 123]
간단한 코드라면 Main 클래스에서 작업 내용을 람다식으로 구현하고, @Bean
어노테이션을 활용하여 빈으로 등록하여 간소화할 수 있습니다.
@SpringBootApplication
@Slf4j
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
@Bean
CommandLineRunner commandLineRunner(){
return args -> {
log.info("{}", args);
};
}
}
ApplicationRunner
역시 마찬가지로 함수형 인터페이스로써 스프링 애플리케이션이 구동된 후에 실행되어야 하는 빈을 정의하기 위한 인터페이스입니다.
목적 자체는 동일하지만 ApplicationRunenr
는 CommandLineRunner
와 달리 다양한 종류의 파라미터를 받아서실행하는 경우에 사용할 수 있습니다.
또한, CommandLineRunner
는 스프링 부트 1.0에 추가된 반면에 ApplicationRunner
는 스프링 부트 2.0에 추가되었습니다.
ApplicationRunner도 CommandLineRunner와 유사하게 인터페이스를 구현하는 클래스를 등록하거나, 람다식으로 직접 사용할 수 있습니다.
아래 코드는 Spring Boot에서 제공하는 ApplicationRunner 인터페이스 명세입니다.
package org.springframework.boot;
@FunctionalInterface
public interface ApplicationRunner {
void run(ApplicationArguments args) throws Exception;
}
ApplicationRunner는 run() 메소드
에서 ApplicationArguments
객체를 파라미터 인자로 받고 있습니다. ApplicationArguments 인터페이스 코드를 살펴보면 아래와 같습니다
package org.springframework.boot;
import java.util.List;
import java.util.Set;
public interface ApplicationArguments {
String[] getSourceArgs();
Set<String> getOptionNames();
boolean containsOption(String name);
List<String> getOptionValues(String name);
List<String> getNonOptionArgs();
}
각 메소드 별 설명은 다음과 같습니다.
ApplicationArguments
- getSourceArgs(): 명령 인자 모두를 문자열 배열로 반환. 옵션 인수(ex: --myOption=value)와 옵션이 아닌 인수가 모두 포함됨.
- getOptionNames(): 명령줄 인수에 있는 고유한 옵션 이름을 반환
- containsOption(String name): 지정된 옵션 이름이 명령줄 인수에 있는지 확인
- getOptionValues(String name): 지정된 옵션 이름과 연관된 값 목록을 반환
- getNonOptionArgs(): 키가 없는 인수인 옵션이 아닌 인수의 목록을 반환
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
@Slf4j
public class TestRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("ApplicationRunner is running!");
// Get the non-option arguments (arguments without keys)
log.info("Non-option arguments: " + args.getNonOptionArgs());
// Get all arguments including options
log.info("All arguments: {}", Arrays.toString(args.getSourceArgs()));
// Get all options
log.info("All options: {}", args.getOptionNames());
// Check if an option is present
if (args.containsOption("myOption")) {
log.info("The 'myOption' is present!");
}
// Access specific option values
List<String> values = args.getOptionValues("myOption");
if (values != null) {
log.info("Values of 'myOption': {}", values);
}
}
}
IntelliJ
에서 실행 옵션을 넣어 코드를 실행합니다.
프로그램을 실행해보면 다음과 같이 로그가 생성됩니다.
TestRunner : ApplicationRunner is running!
TestRunner : Non-option arguments: [value2]
TestRunner : All arguments: [--myOption=value1, value2]
TestRunner : All options: [myOption]
TestRunner : The 'myOption' is present!
TestRunner : Values of 'myOption': [value1]
이번 포스팅에서는 스프링 부트 구동 시점에 특정 작업을 수행하는 두가지 방법에 대해 설명했습니다.
도움이 되셨으면 좋겠습니다.😊💖
좋은 정보 감사합니다