ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 외부 설정 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
Designed by Tistory.