春ブーツに使用され、我々はすべてをすばやくます。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研究所:「春のブートビデオチュートリアル家族のバケット」