コマンド引数は、ソースコードの解析を詳細に説明し、春のブートを開始します

春ブーツに使用され、我々はすべてをすばやくます。java -jarを通じて春のブートプロジェクトを開始することができることを知っています。一方、コンフィギュレーションは、JAR -jarを行う際にパラメータを渡すことによって行われてもよいです。この資料では、システムの機能と関連するソースコード解析春ブートコマンドライン引数を見て歩きます。

コマンドラインパラメータ

あなたは春のブートプロジェクトを開始するとき、私たちは、次のパラメータを経由して渡すことができます。

java -jar xxx.jar --server.port=8081

上記のパラメータは、コマンドラインパラメータを渡して、ポート8081に変更し、より高い優先順位を有することにより、デフォルトポート8080を使用してスプリングブーツは、他の構成パラメータは、同じ名前を上書き。

春のブートパスパラメータプロジェクトを開始するときに、フォーム内の3つのパラメータがあります。

  • オプションパラメータ
  • 非オプションの引数
  • システムパラメータ

オプションパラメータは、上記の例では、「--server.port」を通じてポートアプリケーションを設定するためのオプション・パラメータを使用することです。基本フォーマット「--name =値」(「 - 」二つの連続マイナスの場合)。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;
}

システムパラメータは、java.lang.Systemのに提供される方法によって得ることができます。

String systemServerPort = System.getProperty("server.port");

パラメータの値の差

パラメータの値との差異については、フォーカス・オプションおよびシステムパラメータを見てください。上記の例とは、オプションパラメータを使用する場合は、コマンドにパラメータがxxx.jar後ろに渡され、システムパラメータがすぐます。java -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.

ジャーバックパックのシステムパラメータ場合は、問題が悪化します。そこ正常なスタートになりますが、パラメータが効果を取ることができません。時々明らかにパラメータを渡しますが、位置パラメータ間違ったので、それはおそらく、発効していない理由です。

このエラーは、ほとんどのピットなので、心に留めておくようにしてください:-Dパラメータは、システムを通過し、実行するためにパッケージする前にjarファイルを配置するようにしてください。

あなたは、フォーム@valueシステムパラメータとオプションのパラメータを得ることができますが、唯一のはSystem.getPropertyシステム・パラメータの方法によって得ることができる。もう一つの重要な違いがあります。

ApplicationArgumentsの決意

上述のパラメータは、特定の実施例の使用を見て、次のインタフェース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";
    }
}

ApplicationArgumentsを注入することによって、それはインタフェースメソッドは、パラメータ情報に対応する処理で得ることができる呼び出し、インターフェース。

ApplicationArgumentsインタフェースは、配列リスト、オプションパラメータ、パラメータリストの元のパラメータをカプセル化し、オプションおよび非オプションのパラメータは、起動時に検査を得ました。関連するソースコードを次のように:

public interface ApplicationArguments {

    /**
     * 原始参数数组(未经过处理的参数)
     */
    String[] getSourceArgs();

    /**
     * 选项参数名称
     */
    Set<String> getOptionNames();

    /**
     * 根据名称校验是否包含选项参数
     */
    boolean containsOption(String name);

    /**
     * 根据名称获得选项参数
     */
    List<String> getOptionValues(String name);

    /**
     * 获取非选项参数列表
     */
    List<String> getNonOptionArgs();
}

解析コマンドライン引数

オブジェクトが作成されるとき、それがスプリング容器に注入したときに直接注入し、上記の方法のApplicationArgumentsの使用は、それは、ありますか?

runメソッドの実行中にパラメータを渡されるSpringApplication、およびApplicationArgumentsオブジェクトとしてカプセル化されました。関連するソースコードは次のとおりです。

public ConfigurableApplicationContext run(String... args) {
        
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        // ...
        prepareContext(context, environment, listeners, // ...
    } catch (Throwable ex) {
        // ...
    }
    return context;
}

上記のコードでは、コマンドラインを完了するためのパラメータは、その実装DefaultApplicationArgumentsのクラスを作成することによって解析されます。

DefaultApplicationArgumentsコードの一部を次のように:

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<String> getOptionValues(String name) {
        List<String> values = this.source.getOptionValues(name);
        return (values != null) ? Collections.unmodifiableList(values) : null;
    }

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

メソッドを構築することによって、引数はメンバ変数引数、インタフェースはクラス値で引数のApplicationArgumentsに戻される実現getSourceArgs方法に割り当てられます。

あなたがソースオブジェクトがその親クラスSimpleCommandLinePropertySourceのコンストラクタを呼び出して作成するときに、メンバ変数ソースを設定(内部)の場合:

public SimpleCommandLinePropertySource(String... args) {
    super(new SimpleCommandLineArgsParser().parse(args));
}

プロセスでは、実際のパーサSimpleCommandLineArgsParserの作成と解析パラメータへの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コンテナは完全に呼ばれるプロセスのSpringApplication#実行方法を介して依然として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);
    // ...
}

ApplicationArguments春ブーツのこれまでのところ、関連するソース解析が完了しました。

オリジナルリンク:「春とブート起動コマンドの引数詳細なソースコードの解析

春テクノロジーのビデオ

CSDN研究所:「春のブートビデオチュートリアル家族のバケット」


新しい地平線プログラム :エキサイティングで成長を見逃してはなりません

新しい地平線プログラム - マイクロチャンネル公衆数

おすすめ

転載: www.cnblogs.com/secbro/p/12080818.html