如何通过YAML配置文件实例化带对象参数的新对象,可选不同聚类算法实现
解决方案
要实现包含抽象类/接口子类的Configuration实例自动反序列化,首先需要给你使用的YAML序列化框架(Java生态常用Jackson YAML)配置多态类型绑定,避免框架无法判断抽象类对应的具体实现类。
第一步:给抽象类加多态标识注解
以Jackson框架为例,你需要给抽象类补充类型绑定注解,让框架可以通过YAML里的标识字段匹配到具体实现类:
// 给AbstractAlgorithm加多态注解 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "algoType") @JsonSubTypes({ @JsonSubTypes.Type(value = KMedoids.class, name = "kMedoids"), @JsonSubTypes.Type(value = SpectralClustering.class, name = "spectralClustering"), @JsonSubTypes.Type(value = ConcreteAlgorithm.class, name = "concreteAlgorithm") }) abstract class AbstractAlgorithm{ // 原有逻辑不变 } // 给AbstractParameter加同类型的多态注解,绑定对应的参数实现类 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "paramType") @JsonSubTypes({ @JsonSubTypes.Type(value = CommonParameter.class, name = "commonParam"), @JsonSubTypes.Type(value = ConcreteParameter.class, name = "concreteParam") }) abstract class AbstractParameter{ // 原有逻辑不变 }
第二步:编写对应YAML配置
示例1:使用KMedoids算法的配置
algo: algoType: kMedoids # 和注解里声明的类型名对应,框架用来识别具体算法实现类 abstractParam: k: 3 # KMedoids仅需要的k参数 param1: paramType: commonParam # 和AbstractParameter注解里的类型名对应 timeout: 1000 # 通用参数的自定义属性 param2: OPTION_A # 枚举值直接写枚举常量名即可,框架会自动映射 param3: OPTION_B
示例2:使用SpectralClustering算法的配置
algo: algoType: spectralClustering abstractParam: k: 5 # 光谱聚类特有的参数 graphType: FULLY_CONNECTED # 对应图类型枚举值 laplacianType: NORMALIZED # 对应拉普拉斯类型枚举值 param1: paramType: commonParam timeout: 2000 param2: OPTION_C param3: OPTION_D
示例3:使用你示例中ConcreteAlgorithm的配置
algo: algoType: concreteAlgorithm abstractParam: paramKey: paramValue # 对应AbstractParameter实现类的属性 concreteParam1: ENUM_VALUE_1 # 对应ConcreteEnum.enum1的枚举值 concreteParam2: ENUM_VALUE_2 # 对应ConcreteEnum.enum2的枚举值 param1: paramType: concreteParam field1: val1 # ConcreteParameter对应的自定义属性 field2: val2 param2: ENUM1_OPTION_X param3: ENUM2_OPTION_Y
注意事项
- 枚举类型的参数直接写枚举实例的名称即可,不需要额外处理,主流YAML序列化框架会自动匹配枚举类的常量值。
- 配置文件里的字段名必须和Java类里的属性名严格对应(也可以额外配置字段别名映射),getter、setter方法必须完整,否则会出现属性注入失败的问题。
- 如果你使用的是SnakeYAML等其他序列化框架,只要对应配置好多态类型的映射规则,也可以使用上述结构的YAML配置。
内容的提问来源于stack exchange,提问作者rocksNwaves
相关产品推荐
相关产品推荐

