Spring Boot 시작 명령 파라미터 상세 설명 및 소스 코드 분석

Spring Boot 를 사용 한 적 이 있 습 니 다. 자바 - jar 를 통 해 Spring Boot 프로젝트 를 빠르게 시작 할 수 있다 는 것 을 잘 알 고 있 습 니 다.또한 jar - jar 를 실행 할 때 파 라 메 터 를 전달 하여 설정 할 수 있 습 니 다.본 고 는 Spring Boot 명령 행 파라미터 와 관련 된 기능 과 관련 된 소스 코드 분석 을 체계적으로 알 아 보 겠 습 니 다.
명령 행 매개 변수 사용
Spring Boot 프로젝트 를 시작 할 때 다음 과 같은 방식 으로 인 자 를 전달 할 수 있 습 니 다.
java -jar xxx.jar --server.port=8081

 
기본 적 인 상황 에서 Spring Boot 는 8080 포트 를 사용 하고 상기 매개 변 수 를 통 해 8081 포트 로 수정 하 며 명령 행 을 통 해 전달 하 는 매개 변 수 는 더욱 높 은 우선 순 위 를 가지 고 같은 이름 의 다른 설정 파 라미 터 를 덮어 씁 니 다.
Spring Boot 프로젝트 를 시작 할 때 파 라 메 터 를 전달 합 니 다. 세 가지 매개 변수 형식 이 있 습 니 다.
옵션 매개 변수
비 옵션 매개 변수
시스템 매개 변수
옵션 매개 변 수 는 위의 예제 가 바로 옵션 매개 변수의 사용 방법 입 니 다. "– server. port" 를 통 해 프로그램의 포트 를 설정 합 니 다.기본 형식 은 "– name = value" ("–" 는 연속 두 개의 감호) 입 니 다.그 설정 작용 은 application. properties 에 설 치 된 server. port = 8081 과 같 습 니 다.
비 옵션 매개 변수의 사용 예 는 다음 과 같다.
java -jar xxx.jar abc def 

 
상기 예제 에서 "abc" 와 "def" 는 비 옵션 매개 변수 입 니 다.
시스템 매개 변수, 이 매개 변 수 는 시스템 변수 에 설 정 됩 니 다. 예 를 들 어 다음 과 같 습 니 다.
java -jar -Dserver.port=8081 xxx.jar

 
매개 변수 값 가 져 오기
옵션 매개 변수 와 비 옵션 매개 변 수 는 모두 ApplicationArguments 인 터 페 이 스 를 통 해 얻 을 수 있 으 며, 구체 적 인 획득 방법 은 매개 변 수 를 사용 하 는 클래스 에 이 인 터 페 이 스 를 직접 주입 하면 됩 니 다.
@RestController
public class ArgumentsController {
    @Resource
    private ApplicationArguments arguments;
}

 
ApplicationArguments 인 터 페 이 스 를 통 해 제공 하 는 방법 으로 대응 하 는 인 자 를 얻 을 수 있 습 니 다.이 인터페이스 에 대해 서 는 나중에 자세히 설명 할 것 이다.
또한 옵션 매개 변 수 는 @ Value 를 통 해 클래스 에서 직접 얻 을 수 있 습 니 다. 다음 과 같 습 니 다.
@RestController
public class ParamController {
    @Value("${server.port}")
    private String serverPort;
}

 
시스템 매개 변 수 는 자바. lang. System 에서 제공 하 는 방법 으로 얻 을 수 있 습 니 다.
String systemServerPort = System.getProperty("server.port");

 
매개 변수 값 의 차이
매개 변수 값 의 차이 에 대해 옵션 매개 변수 와 시스템 매개 변 수 를 중점적으로 봅 니 다.위의 예 시 를 통 해 우 리 는 옵션 파 라 메 터 를 사용 할 때 파 라 메 터 는 명령 에서 xxx. jar 에 위치 한 후에 전달 되 는 것 을 발 견 했 고 시스템 파 라 메 터 는 자바 - jar 에 이 어 전달 되 었 다.
이 순서에 따라 실행 하지 않 으 면 다음 과 같은 방식 으로 옵션 인 자 를 사용 합 니 다.
java -jar --server.port=8081 xxx.jar

 
다음 이상 을 던 집 니 다:
Unrecognized option: --server.port=8081
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

 
시스템 매개 변 수 를 jar 패키지 뒤에 두 면 문제 가 더 심각 합 니 다.정상적으로 시작 할 수 있 지만 매개 변 수 는 유효 하지 않 습 니 다.이것 도 가끔 인 자 를 전달 하 였 으 나 효력 이 발생 하지 않 는 이유 입 니 다. 그것 은 매개 변수의 위 치 를 잘못 썼 기 때 문 일 수 있 습 니 다.
이 오 류 는 가장 함정 에 빠 진 것 이 므 로 명심 하 십시오. - D 를 통 해 시스템 인 자 를 전달 할 때 실행 할 jar 패키지 앞 에 두 어야 합 니 다.
또 하나의 중요 한 차이 점 은 @ Value 형식 을 통 해 시스템 매개 변수 와 옵션 매개 변 수 를 얻 을 수 있 지만 System. getProperty 방법 을 통 해 시스템 매개 변수 만 얻 을 수 있다 는 것 이다.
응용 프로그램 Arguments 해석
위 에서 언급 한 것 은 ApplicationArguments 인 터 페 이 스 를 주입 하여 관련 매개 변 수 를 얻 을 수 있 습 니 다. 다음은 구체 적 인 사용 예 시 를 살 펴 보 겠 습 니 다.
@RestController
public class ArgumentsController {

    @Resource
    private ApplicationArguments arguments;

    @GetMapping("/args")
    public String getArgs() {

        System.out.println("#        : "   arguments.getNonOptionArgs().size());
        System.out.println("#       : "   arguments.getOptionNames().size());
        System.out.println("#        :");
        arguments.getNonOptionArgs().forEach(System.out::println);

        System.out.println("#         :");
        arguments.getOptionNames().forEach(optionName -> {
            System.out.println("--"   optionName   "="   arguments.getOptionValues(optionName));
        });

        return "success";
    }
}

 
응용 프로그램 Arguments 인 터 페 이 스 를 주입 한 후 방법 에서 이 인 터 페 이 스 를 호출 하 는 방법 으로 대응 하 는 매개 변수 정 보 를 얻 을 수 있 습 니 다.
ApplicationArguments 인터페이스 에 시작 할 때 원본 매개 변수의 배열, 옵션 매개 변수의 목록, 비 옵션 매개 변수의 목록 과 옵션 매개 변수 획득 과 검 사 를 봉인 합 니 다.관련 소스 코드 는 다음 과 같 습 니 다.
public interface ApplicationArguments {

    /**
     *       (        )
     */
    String[] getSourceArgs();

    /**
     *       
     */
    Set getOptionNames();

    /**
     *               
     */
    boolean containsOption(String name);

    /**
     *           
     */
    List getOptionValues(String name);

    /**
     *          
     */
    List getNonOptionArgs();
}

 
명령 행 매개 변수 분석
위 에 ApplicationArguments 의 주입 과 방법 을 직접 사 용 했 습 니 다. 대상 은 언제 만 들 어 졌 고 스프링 용기 에 언제 주입 되 었 습 니까?
SpringApplication 의 run 방법 을 실행 하 는 과정 에서 들 어 오 는 인 자 를 얻 고 applicationArguments 대상 으로 봉 합 니 다.관련 소스 코드 는 다음 과 같 습 니 다.
public ConfigurableApplicationContext run(String... args) {
        
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        // ...
        prepareContext(context, environment, listeners, // ...
    } catch (Throwable ex) {
        // ...
    }
    return context;
}

 
위 코드 에서 구현 클래스 DefaultApplicationArguments 를 만들어 명령 행 매개 변 수 를 분석 합 니 다.
기본 응용 프로그램 Arguments 부분 코드 는 다음 과 같 습 니 다.
public class DefaultApplicationArguments implements ApplicationArguments {

    private final Source source;
    private final String[] args;

    public DefaultApplicationArguments(String... args) {
        Assert.notNull(args, "Args must not be null");
        this.source = new Source(args);
        this.args = args;
    }
    
    // ...

    @Override
    public List getOptionValues(String name) {
        List values = this.source.getOptionValues(name);
        return (values != null) ? Collections.unmodifiableList(values) : null;
    }

    private static class Source extends SimpleCommandLinePropertySource {
        Source(String[] args) {
            super(args);
        }
        // ...
    }
}

 
구조 방법 을 통 해 args 를 구성원 변수 args 에 할당 합 니 다. 그 중에서 인터페이스 ApplicationArguments 에서 getSourceArgs 방법의 실현 은 이 클래스 에서 args 값 을 되 돌려 줍 니 다.
구성원 변수 Source (내부 클래스) 에 대한 설정 은 Source 대상 을 만 들 때 부모 클래스 Simple CommandLine Property Source 의 구조 방법 을 호출 합 니 다.
public SimpleCommandLinePropertySource(String... args) {
    super(new SimpleCommandLineArgsParser().parse(args));
}

 
이 방법 에서 실제 해상도 기 Simple CommandLineargs Parser 를 만 들 고 parse 방법 으로 파 라 메 터 를 분석 합 니 다.
class SimpleCommandLineArgsParser {

    public CommandLineArgs parse(String... args) {
        CommandLineArgs commandLineArgs = new CommandLineArgs();
        for (String arg : args) {
            // --        
            if (arg.startsWith("--")) {
                //   key=value key 
                String optionText = arg.substring(2, arg.length());
                String optionName;
                String optionValue = null;
                //    key=value       
                if (optionText.contains("=")) {
                    optionName = optionText.substring(0, optionText.indexOf('='));
                    optionValue = optionText.substring(optionText.indexOf('=') 1, optionText.length());
                } else {
                    //      key(--foo)     
                    optionName = optionText;
                }
                //   optionName    optionValue    optionName       
                if (optionName.isEmpty() || (optionValue != null && optionValue.isEmpty())) {
                    throw new IllegalArgumentException("Invalid argument syntax: "   arg);
                }
                //    CommandLineArgs
                commandLineArgs.addOptionArg(optionName, optionValue);
            } else {
                commandLineArgs.addNonOptionArg(arg);
            }
        }
        return commandLineArgs;
    }
}

 
상기 해석 규칙 은 비교적 간단 하 다. 바로 '–' 와 '=' 에 따라 서로 다른 매개 변수 유형 을 구분 하고 해석 하 는 것 이다.
위의 방법 을 통 해 ApplicationArguments 의 실현 클래스 의 대상 을 만 들 었 으 나 아직 Spring 용 기 를 주입 하지 않 았 습 니 다. Spring 용 기 를 주입 하 는 것 은 상기 SpringApplication \ # run 방법 에서 호출 된 prepareContext 방법 을 통 해 이 루어 집 니 다.관련 코드 는 다음 과 같 습 니 다.
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
        SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    // ...
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    //   beanFactory ApplicationArguments     Spring  
    beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    // ...
}

 
이로써 Spring Boot 에서 ApplicationArguments 와 관련 된 소스 코드 분석 이 완료 되 었 습 니 다.
————————————————
저 는 자바 고급 자 료 를 무료 로 정 리 했 습 니 다. 자바, Redis, MongoDB, MySQL, Zookeeper, Spring Cloud, Dubbo 고 병발 분포 식 등 튜 토리 얼 을 포함 하여 모두 30G 이 므 로 스스로 수령 해 야 합 니 다.전송 문:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ

좋은 웹페이지 즐겨찾기