前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[享学Netflix] 六、Apache Commons Configuration2.x工具Parameters和Configurations

[享学Netflix] 六、Apache Commons Configuration2.x工具Parameters和Configurations

作者头像
YourBatman
发布2020-03-18 19:32:29
4630
发布2020-03-18 19:32:29
举报
文章被收录于专栏:BAT的乌托邦BAT的乌托邦

极致之路,没有银弹。不要想着一招毙命,一口吃成个胖子,而是要审时度势,结合当前状况来裁定。 代码下载地址:https://github.com/f641385712/netflix-learning

目录
  • 前言
  • 正文
    • Parameters
      • DefaultParametersHandler
      • DefaultParametersManager
      • 使用示例
    • Configurations
      • 使用示例
  • 总结
    • 声明

前言

上篇文章完整的介绍了Commons Configuration的Builder机制,并且辅以示例介绍了如何使用。

Commons Configuration2.x推荐我们使用Builder去构建一个Configuration实例,但奈何实际使用起来着实比较麻烦,怎么破? 本文将介绍两个“工具类”:ParametersConfigurations,分别能够简化你对参数的构建和对Builder构建器创建过程,当然还包含一步到位的直接构建出Configuration实例的方法。

说明:说这两个API是工具类有点牵强,毕竟方法都不是static静态方法~


正文

构建一个BuilderParameters或者一个Configuration的步骤是较为繁琐的,这两个API就是为简化这些步骤而生。

说明:Xxxs结尾经常用于表示帮助类、工具类,形如Collections、Arrays等等…


Parameters

一个工具类,用于创建用于初始化的参数对象配置生成器对象。 与它相关的还有两个API需要先行介绍:DefaultParametersHandlerDefaultParametersManager


DefaultParametersHandler

用于设置特定的默认值的接口。

代码语言:javascript
复制
public interface DefaultParametersHandler<T> {
	void initializeDefaults(T parameters);
}

这个接口很简单:为指定参数T设置默认值。它有唯一实现类CopyObjectDefaultHandler用于给BuilderParameters设置默认值。

说明:CopyObjectDefaultHandler虽然是内置的唯一实现类,但是并没有被系统用到过,使用者可按需自取

代码语言:javascript
复制
public class CopyObjectDefaultHandler implements DefaultParametersHandler<Object> {

	private final BuilderParameters source;
	... // 省略构造器和get方法


    @Override
    public void initializeDefaults(final Object parameters) {
        try {
            BeanHelper.copyProperties(parameters, getSource().getParameters());
            BeanHelper.copyProperties(parameters, getSource());
        } catch (final Exception e) {
            throw new ConfigurationRuntimeException(e);
        }
    }
}

CopyObjectDefaultHandler处理方式:仅仅只是把你传进来的BuilderParameters作为source,通过反射复制到目标Object身上而已(注意:目标是Object,而非必须BuilderParameters),个人觉得基本没啥卵用。


DefaultParametersManager

它是用于管理DefaultParametersHandler们的管理器,因为对于一个Class类型上可以有多个DefaultParametersHandler作用于它的,所以又抽象出DefaultHandlerData来加以管理,并且还加入了处理继承、接口实现的匹配的能力(大多情况亦无需关心)。

代码语言:javascript
复制
public class DefaultParametersManager {
	
	// 管理着DefaultParametersHandler的集合
	private final Collection<DefaultHandlerData> defaultHandlers;
	// 线程安全
    public DefaultParametersManager() {
        defaultHandlers = new CopyOnWriteArrayList<>();
    }
    ...

	// 向管理器注册一个DefaultParametersHandler
    public <T> void registerDefaultsHandler(final Class<T> paramsClass, final DefaultParametersHandler<? super T> handler, final Class<?>  startClass) {
    	...
    	defaultHandlers.add(new DefaultHandlerData(handler, paramsClass, startClass));
    }
    ... // 省略unregisterDefaultsHandler方法

	// 这是它最重要的一个方法:给BuilderParameters设置初始化值
	// 这时候注册在它上面的所有的`DefaultParametersHandler#initializeDefaults`都会执行
	// 该方法在代理对象创建完成后,立马会执行initializeParameters方法完成初始化
    public void initializeParameters(final BuilderParameters params) {
        if (params != null) {
            for (final DefaultHandlerData dhd : defaultHandlers) {
                dhd.applyHandlerIfMatching(params);
            }
        }
    }
}

对于每个Class类型是可以有多个DefaultParametersHandler为它设置默认值的,initializeParameters()方法会在每次代理对象创建后,完成初始化赋值操作,也算是给调用者留的一个钩子。


介绍完两个前置API,下面正式看看Parameters提供的API们,我截图如下:

在这里插入图片描述
在这里插入图片描述

部分源码解读:

代码语言:javascript
复制
Parameters:

	// 为指定类型配置一个DefaultParametersHandler,用于自动设置初始值
    public <T> void registerDefaultsHandler(final Class<T> paramsClass, final DefaultParametersHandler<? super T> handler) {
        getDefaultParametersManager().registerDefaultsHandler(paramsClass, handler);
    }


	// 因BasicXXX不是抽象类,所以直接new即可得到实例
    public BasicBuilderParameters basic() {
        return new BasicBuilderParameters();
    }
    // 请注意:返回的是这个接口的JDK动态代理对象~~~
    public FileBasedBuilderParameters fileBased() {
        return createParametersProxy(new FileBasedBuilderParametersImpl(), FileBasedBuilderParameters.class);
    }
    public CombinedBuilderParameters combined() { ... }
    ...
    public XMLBuilderParameters xml()
    public PropertiesBuilderParameters properties()
    ...

精妙之处在于:XMLBuilderParameters/XMLBuilderParameters这些均是接口,这里通过Parameters生成代理,使得这些接口便可直接使用了,非常方面。这种通用设计(代理对象的生成)是非常值得点赞的~

FileBasedBuilderParametersFileBasedBuilderParametersImpl的区别

  1. 后者并不是前者(接口的实现类),即使命名上看其起来非常像
  2. 两者均实现了接口FileBasedBuilderPropertiesBasicBuilderProperties,可以设置FileBased属性和基本属性
  3. 两者均是BuilderParameters的实现

总的来说,两者功能相似,FileBasedBuilderParameters需要结合Parameters一起使用,而后者使用者可单独使用。


使用示例

非常经典的使用案例:

代码语言:javascript
复制
@Test
public void fun4() throws ConfigurationException {
    FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class);
    Parameters params = new Parameters();

    // 配置一个FileBased参数即可
    FileBasedBuilderParameters builderParameters = params.fileBased().setThrowExceptionOnMissing(true)
            .setEncoding("UTF-8")
            .setListDelimiterHandler(new DefaultListDelimiterHandler(','))
            .setFileName("1.properties");
    builder.configure(builderParameters);

	System.out.println(builderParameters.getClass());
    ConfigurationUtils.dump(builder.getConfiguration(),System.out);
}

控制台打印:

代码语言:javascript
复制
class com.sun.proxy.$Proxy4 // 可以看到 builderParameters是个JDK代理对象哦
common.name=YourBatman
common.age=18
common.addr=China
common.count=4
common.fullname=${common.name}-Bryant
java.version=1.8.123

至少可以看到,在参数构建BuilderParameters方面,比之前优雅了很多。


Configurations

如果Parameters你感觉离得稍远,那么Configurations这个类你不应该陌生。

它也是,一个工具类,它简化了标准配置的创建和他们的Builder们。也就是说它能方便的创建builder实例,也能一步到位的方便创建出Configuration实例。

部分源码解读:

代码语言:javascript
复制
public class Configurations {

	// BuilderParameters等等统一交给它来构建喽
	private final Parameters parameters;
	... // 省略构造器

	// 快速构建出一个FileBasedConfigurationBuilder实例
	// 它可以构建出形如PropertiesConfiguration
    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final File file) {
        return createFileBasedBuilder(configClass, fileParams(file));
    }
    ... // 省略重载方法

	// 注意和上面的区别哦:此处一步到位,返回的就是一个Configuration实例
    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final String path) throws ConfigurationException {
        return fileBasedBuilder(configClass, path).getConfiguration();
    }

	... // 同理还有如下搭配
	// propertiesBuilder()/properties()
	// xmlBuilder()/xml()
	// iniBuilder()/ini()
	// combinedBuilder()/combined()
}

源码解读够直接、够简单,因为这个工具类没太好好说的,看个使用示例一学便会。


使用示例
代码语言:javascript
复制
@Test
public void fun5() throws ConfigurationException {
    // 当然,绝大多数情况下,空构造new Configurations()即可
    // Parameters params = new Parameters();
    // Configurations configs = new Configurations(params);

    Configurations configs = new Configurations();
    PropertiesConfiguration configuration = configs.properties("1.properties");
    ConfigurationUtils.dump(configuration,System.out);
}

运行程序,控制台打印同上。


总结

关于Commons Configuration2.x快速构建工具类Parameters和Configurations就介绍到这了,看完之后有木有一种爽感,编码过程再一次得到了解放有木有~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 前言
  • 正文
    • Parameters
      • DefaultParametersHandler
      • DefaultParametersManager
      • 使用示例
    • Configurations
      • 使用示例
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档