-
외부 설정 3 - 커맨드 라인 인수스프링/스프링부트 2023. 9. 30. 15:20
커맨드 라인 인수는 애플리케이션 실행 시점에 외부 설정값을 main(args) 메서드의 args 파라미터로 전달하는 방법이다.
java -jar app.jar dataA dataB와 같이 사용된다.
필요한 데이터를 마지막 위치에 스페이스로 구분해서 전달한다. 위의 방법에서는 dataA, dataB 2개의 문자가 args에 전달된다.
사진의 동그라미 부분에 dataA, dataB를 넣어준다. 이 때, 한 칸 띄어쓰기 하는 것은 꼭 필요하다.
@Slf4j public class CommandLineV1 { public static void main(String[] args) { for (String arg : args) { log.info("arg {}", arg); } } }
테스트코드로 args를 하나씩 출력해보면 아래처럼 나온다.
jar 실행
jar로 빌드가 되어있다면 아래와 같이 커맨드 라인 인수를 추가할 수 있다.
java -jar project.jar dataA dataB
url=devdb username=dev_user password=dev_pw와 같이 key=value로 입력하면 key, value가 들어가는 것이 아니라 띄어쓰기를 기준으로 문자가 그대로 들어가는 것이다. 커맨드 라인 인수를 key=value 형식이 아니기 때문에 무조건 띄어쓰기를 기준으로 문자를 입력해야 한다.
만약에 이렇게 한다면 개발자가 =을 기준으로 직접 데이터를 파싱해서 분리해야하기 때문에 불편함이 있다.
하지만 이런 불편함을 스프링에서 해결해준다.
커맨드 라인 옵션 인수
커맨드 라인 인수를 key=value 형식으로 구분하는 방법이 필요해서 스프링에서 표준 방식을 정의한 것이다.
스프링은 커맨드 라인에 - (dash) 2개( -- )를 연결해서 시작하면 key=value 형식으로 정하고 이것을 커맨드 라인 옵션 인수라 한다.
--key=value 형식으로 사용한다.--username=userA --username=userB 하나의 키에 여러 값도 지정할 수 있다.--url=devdb --username=dev_user --password=dev_pw mode=on라고 넣어줬다. 마지막에 mode=on을 넣은 것은 --를 붙이지 않았을 때의 차이를 확인하기 위한 것이다.
@Slf4j public class CommandLineV2 { public static void main(String[] args) { for (String arg : args) { log.info("arg {}", arg); } ApplicationArguments appArgs = new DefaultApplicationArguments(args); log.info("OptionsNames = {}", appArgs.getOptionNames()); Set<String> optionNames = appArgs.getOptionNames(); for (String optionName : optionNames) { log.info("option arg {}={}", optionName, appArgs.getOptionValues(optionName)); } List<String> url = appArgs.getOptionValues("url"); List<String> username = appArgs.getOptionValues("username"); List<String> password = appArgs.getOptionValues("password"); List<String> mode = appArgs.getOptionValues("mode"); log.info("url={}", url); log.info("username={}", username); log.info("password={}", password); log.info("mode={}", mode); } }
ApplicationArguments 인터페이스로 new DefaultApplicationArguments를 생성하고 파라미터에 args를 넘겨주면 커맨드 라인 옵션 인수를 사용할 수 있다.
반환 타입이 List인 것은 value를 여러개 가질 수 있기 때문이다.
출력 결과를 확인하면 커맨드 라인 옵션 인수를 사용하지 않았을 때에는 문자들이 통으로 들어갔지만 커맨드 라인 옵션 인수 사용 후에는 key와 value가 자동으로 파싱 되었다. mode를 보면 --가 없기 때문에 key=value로 들어가지 않아서 getOption() 등의 메서드로 추출할 수 없다.
커맨드 라인 옵션 인수와 스프링 부트
스프링 부트는 커맨드 라인을 포함해서 커맨드 라인 옵션 인수를 활용할 수 있는 ApplicationArguments를 스프링 빈으로 등록한 다음 입력한 커맨드 라인을 저장해둔다.
해당 빈을 주입 받으면 커맨드 라인으로 입력한 값을 어디서든 사용할 수 있다.
@Slf4j @Component public class CommandLineBean { private final ApplicationArguments arguments; public CommandLineBean(ApplicationArguments arguments) { this.arguments = arguments; } // 아래는 그냥 프로그램 실행 시점에 로그로 확인하기 위한 용도 @PostConstruct public void init() { log.info("source {}", List.of(arguments.getSourceArgs())); log.info("optionNames {}", arguments.getOptionNames()); Set<String> optionNames = arguments.getOptionNames(); for (String optionName : optionNames) { log.info("option args {}={}", optionName, arguments.getOptionValues(optionName)); } } }
@Component 어노테이션으로 스프링 빈으로 주입이 되며 스프링 어디에서나 커맨드 라인으로 입력한 값을 사용할 수 있다. 생성자로 인해서 인수가 자동으로 들어간다.
@SpringBootApplication public class ExternalApplication { public static void main(String[] args) { SpringApplication.run(ExternalApplication.class, args); } }
main 메서드가 run할 때 args가 넘어가는데, CommandLineBean이 주입이 된다.
main 메서드에도 program argument를 넣어주고 실행을 해보면
이런 로그가 뜨는 것을 확인할 수 있다. --가 없는 mode는 테스트용이며 다른 인수들은 스프링 어디에서든 사용할 수 있다.
꼭 main 메서드가 아니라 스프링의 어느 빈에서라도 주입받으면 application argument들을 꺼내서 사용할 수 있다.
'스프링 > 스프링부트' 카테고리의 다른 글
외부 설정 4 - 설정 데이터 (0) 2023.09.30 외부 설정 - 스프링 통합 (0) 2023.09.30 외부 설정 2 - 자바 시스템 속성 (0) 2023.09.30 외부 설정 1 - OS 환경 변수 (0) 2023.09.30 외부 설정이란? (0) 2023.09.30