728x90
커맨드 라인 인수
커맨드 라인 인수(Command line arguments)는 애플리케이션 실행 시점에 외부 설정값을 main(args) 메서드의 args 파라미터로 전달하는 방법이다.
- 예) java -jar app.jar dataA dataB
- 필요한 데이터를 마지막 위치에 스페이스로 구분해서 전달하면 된다. 이 경우 dataA , dataB 2개의 문자가 args 에 전달된다.
CommandLineV1
@Slf4j
public class CommandLineV1 {
public static void main(String[] args) {
for (String arg : args) {
log.info("arg = {}", arg); //Key=value 형식이 아니다.
String[] keyValue = arg.split("=");
log.info("key = {}, value = {}", keyValue[0], keyValue[1]); //개발자가 직접 파싱해야한다
}
}
}

- 커맨드 라인 인수는 공백(space)으로 구분한다.
- 커맨드 라인 인수는 key=value 형식이 아니다. 단순히 문자를 여러게 입력 받는 형식이다.
- arg에 아래와 같은 값이 통으로 들어오기 떄문에 개발자가 = 을 기준으로 직접 데이터를 파싱해서 key=value 형식에 맞도록 분리해야 한다.
-
url=devdb
-
username=dev_user
-
password=dev_pw
-
- 그리고 형식이 배열이기 때문에 루프를 돌면서 원하는 데이터를 찾아야 하는 번거로움도 발생한다.
- 실제 애플리케이션을 개발할 때는 주로 key=value 형식을 자주 사용하기 때문에 결국 파싱해서 Map 같은 형식으로 변환하도록 직접 개발해야 하는 번거로움이 있다.
- arg에 아래와 같은 값이 통으로 들어오기 떄문에 개발자가 = 을 기준으로 직접 데이터를 파싱해서 key=value 형식에 맞도록 분리해야 한다.
커멘드 라인 옵션 인수
일반적인 커맨드 라인 인수
커맨드 라인에 전달하는 값은 형식이 없고, 단순히 띄어쓰기로 구분한다.
- aaa bbb -> [aaa, bbb] : 값 2개
- hello world -> [hello, world] : 값 2개
- "hello world" -> [hello world] (공백을 연결하려면 " 를 사용하면 된다.) : 값 1개
- key=value -> [key=value] : 값 1개
커맨드 라인 옵션 인수(command line option arguments)
커맨드 라인 인수를 key=value 형식으로 구분하는 방법이 필요하다. 그래서 스프링에서는 커맨드 라인 인수를 key=value 형식으로 편리하게 사용할 수 있도록 스프링 만의 표준 방식을 정의했는데, 그것이 바로 커맨드 라인 옵션 인수이다.
스프링은 커맨드 라인에 - (dash) 2개( -- )를 연결해서 시작하면 key=value 형식으로 정하고 이것을 커맨드 라인 옵션 인수라 한다.
- --key=value 형식으로 사용한다.
- --username=userA --username=userB 하나의 키에 여러 값도 지정할 수 있다.
CommandLineV2
@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("SourceArgs = {}", List.of(appArgs.getSourceArgs())); //배열을 참조값을 반환해서 값을 보기 위해 list로 변경
log.info("NoneOptionsArgs = {}", appArgs.getNonOptionArgs());
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); //통문자라 key-value 형식으로 못 뽑는다.
}
}
}

- 스프링이 제공하는 ApplicationArguments 인터페이스와 DefaultApplicationArguments 구현체를 사용하면 커맨드 라인 옵션 인수를 규격대로 파싱해서 편리하게 사용할 수 있다.
- -- (dash)가 없는 mode=on 이라는 옵션도 마지막에 추가했다.
- 실행 결과
- arg : 커맨드 라인의 입력 결과를 그대로 출력한다.
- SourceArgs : 커맨드 라인 인수 전부를 출력한다.
- NonOptionArgs = [mode=on] : 옵션 인수가 아니다. key=value 형식으로 파싱되지 않는다. -- 를 앞에 사용하지 않았다.
- OptionNames = [password, url, username] : key=value 형식으로 사용되는 옵션 인수다. -- 를 앞에 사용했다.
- url , username , password 는 옵션 인수이므로 appArgs.getOptionValues(key) 로 조회할 수 있다.
- mode 는 옵션 인수가 아니므로 appArgs.getOptionValues(key) 로 조회할 수 없다. 따라서 결과는 null 이다
참고
- 참고로 옵션 인수는 --username=userA --username=userB 처럼 하나의 키에 여러 값을 포함할 수 있기 때문에 appArgs.getOptionValues(key) 의 결과는 리스트( List )를 반환한다.
- 커맨드 라인 옵션 인수는 자바 언어의 표준 기능이 아니다. 스프링이 편리함을 위해 제공하는 기능이다.
커맨드 라인 옵션 인수와 스프링 부트
스프링 부트는 커맨드 라인을 포함해서 커맨드 라인 옵션 인수를 활용할 수 있는 ApplicationArguments를 스프링 빈으로 등록해 둔다.. 그리고 그 안에 입력한 커맨드 라인을 저장해 둔다.. 그래서 해당 빈을 주입받으면 커맨드 라인으로 입력한 값을 어디서든 사용할 수 있다.
CommandLineBean
@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 {}", List.of(arguments.getOptionNames()));
Set<String> optionNames = arguments.getOptionNames();
for (String optionName : optionNames) {
log.info("option args {} = {}", optionName, arguments.getOptionValues(optionName));
}
}
}

- main 메서드의 SpringApplication.run(ExternalApplication.class, args); 실행 시, 인자로 넘어간 args를 스프링이 등록해 준다.
728x90
'스프링 부트(핵심 원리와 활용)' 카테고리의 다른 글
| Ch05. 외부설정과 프로필(1) - 설정 데이터(외부 파일) (0) | 2023.03.12 |
|---|---|
| Ch05. 외부설정과 프로필(1) - 외부 설정(자바 시스템 속성) (0) | 2023.03.12 |
| Ch05. 외부설정과 프로필(1) - 외부 설정(자바 시스템 속성) (0) | 2023.03.12 |
| Ch05. 외부설정과 프로필(1) - 외부 설정(OS 환경 변수) (0) | 2023.03.12 |
| Ch05. 외부설정과 프로필(1) - 외부 설정이란? (0) | 2023.03.12 |