当前位置: 首页 > 工具软件 > JCommander > 使用案例 >

java接口 传外参_JCommander:Java外部参数解析利器

戚鸿福
2023-12-01

13/Mar 2015

最近需要把项目交给别人进行运维,为了不让接手之人涉及太多繁琐细节,我把一些定义在final类中的不可变量抽取出来,把项目变成可外部配置的。用配置文件可以达到这个目的,但由于配置之间有相互依赖关系,比如:

public static boolean local = false;

public static String host = (local) ? "127.0.0.1" : "172.16.3.142";

public static int port = (local) ? 6379 : 6380;

原本只需要改变local, 用配置文件的话与local值有依赖关系的地方都要面临修改。

后来打算用命令行参数实现可外部动态配置,如果自己动手实现完善的命令行参数解析,可不是一项little job。 比较了几款开源的工具,还是选择了JCommander。主要原因是被它官网的slogan打动了:

Because life is too short to parse command line parameters.

项目是maven构建的,使用JCommander的方式十分简单:

com.beust

jcommander

使用JCommander的方式也很简单,给需要外部传参的变量加Parameter标注:

@Parameter(names = { "-topologyName"}, description = "Topology name.")

private static String TOP_NAME = "sz-train";

一般类型参数后面都要跟值,JCommander会根据对应变量做类型检查和转换,不合法时会抛出异常错误。

boolean类型有点特殊,后面不需要跟一个值,输入-local之后,local值即为true:

@Parameter(names = { "-local"}, description = "Local model, default cluster Model.")

public static boolean LOCAL_MODE = false;

如果一个boolean变量的默认值为true,而想通过参数设置为false,可以指定元数:

@Parameter(names = { "-log", "-verbose"}, description = " Wheather to write system log.", arity = 1)

public static boolean LOG = true;

默认情况下,参数是可选的,如果要求必须指定参数,可以设置required:

@Parameter(names = "-operator", required = true)

private String operator;

有时仅仅依靠JCommander的类型检查还不够,还需要自定义检查器提前发现不合法的输入:

@Parameter(names = { "-redisPort"}, description = "Redis port.", validateWith = PortValidator.class)

public static int REDIS_PORT=(LOCAL_MODE) ? 6379:6380;

public static class PortValidator implements IParameterValidator {

public void validate(String name, String value)

throws ParameterException {

Pattern pattern = Pattern.compile("[1-9]\\d*");

Matcher matcher = pattern.matcher(value);

if (matcher.matches()) {

int n = Integer.parseInt(value);

if (n < 65536) {

return;

}

}

throw new ParameterException("Parameter " + name

+ " should be a number(0~65535) (found " + value +")");

}

}

如果是一个写日志的目录,可以提前发现该目录是否可写,这是配置文件无法做到的:

@Parameter(names = { "-logDir"}, description = "Dir to write log file.",

validateWith = DirValidator.class)

public static String LOG_DIR = "/logs/your_project/";

public static class DirValidator implements IParameterValidator {

public void validate(String name, String value)

throws ParameterException {

File file = new File(value);

if (!file.isDirectory() || !file.canWrite()) {

throw new ParameterException("Parameter " + name

+ " should be a writable folder(found " + value +")");

}

}

}

对于IP地址,不仅可以通过正则表达式进行匹配,还可以进行简单的网络连通性探测等。相比基于文本的配置文件,JCommander显示出了强大的优势。

但更多的项目可能还是更适合用配置文件的方式进行外部配置,如果配置文件如果可以吸收JCommander的特点,那就perfect了。我理想中的配置文件应该有如下特性:

- 配置文件本身是programmable

- 可以进行上下文联系

- 自动类型检查和转换

- 可以自定义语义检查器

- 所使用的弱语言可以方便嵌入

Tags//

java,

More Reading

 类似资料: