【问题标题】:Read qualified yaml file with prefix without using annotations or xml在不使用注释或 xml 的情况下读取带前缀的合格 yaml 文件
【发布时间】:2017-12-30 14:12:38
【问题描述】:

我的用例有点奇怪,但基本上,我想读取 yaml 文件的一部分并将其映射到 spring 应用程序中的适当 java 对象。这是 spring 中非常常见且微不足道的操作(只需使用 @ConfigurationProperties )。

但是,就我而言,我想在生命周期的早期完成此读取,即在 BeanFactoryPostProcessor 挂钩时 - 以便使用 yml 中指定的指令来动态创建多个 bean。

我可以使用 application.properties 但不能使用 application.yml

我希望使用 yml 来利用 yml 的映射部分到 POJO,并利用分层映射文件和数据结构(列表、地图等)。

这是一个如何读取 application.properties 的示例。 https://blog.pchudzik.com/201705/dynamic-beans/

我在https://github.com/balamuru/yaml-loader 建立了一个简单的骨架项目来尝试不同的技术。 有什么想法吗?

@Component
@EnableConfigurationProperties(SampleDataConfig.class)
class ConfigurableBeanFactory implements BeanFactoryPostProcessor, InitializingBean {
    private List<String> beanInstances = new ArrayList<>();

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

        Map<String, SampleDataConfig> beans = beanFactory.getBeansOfType(SampleDataConfig.class);
        System.err.println("");

        beanInstances.forEach(instance -> {
            registry.registerBeanDefinition(instance, BeanDefinitionBuilder
                    .rootBeanDefinition(SampleDataConfig.class)
                    .addConstructorArgValue(instance)
                    .getBeanDefinition());
        });
    }

    @Override
    public void afterPropertiesSet() throws Exception {
//        this.beanInstances = asList(PropertiesLoaderUtils
//                .loadProperties(new ClassPathResource("/application.properties"))
//                .getProperty("dynamic-beans.instances", "")
//                .split(","));

        /**
         * Rather than reading from application.properties,
         * I would like to be able to load up the relevant prefix qualified segments (com.foo.bar.stuff) mapping to my POJO (SampleDataConfig,class)
         * loaded from application.yml
         */
    }

}

在内部,spring 使用以下机制,但我希望有一种更简单的方法来利用它而无需重新发明 spring :)

public class ConfigurationPropertiesBindingPostProcessor ...{
.
.

    private void postProcessBeforeInitialization(Object bean, String beanName,
            ConfigurationProperties annotation) {
        Object target = bean;
        PropertiesConfigurationFactory<Object> factory = new PropertiesConfigurationFactory<Object>(
                target);
        factory.setPropertySources(this.propertySources);
        factory.setValidator(determineValidator(bean));
        // If no explicit conversion service is provided we add one so that (at least)
        // comma-separated arrays of convertibles can be bound automatically
        factory.setConversionService(this.conversionService == null
                ? getDefaultConversionService() : this.conversionService);
        if (annotation != null) {
            factory.setIgnoreInvalidFields(annotation.ignoreInvalidFields());
            factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields());
            factory.setExceptionIfInvalid(annotation.exceptionIfInvalid());
            factory.setIgnoreNestedProperties(annotation.ignoreNestedProperties());
            if (StringUtils.hasLength(annotation.prefix())) {
                factory.setTargetName(annotation.prefix()); //====> use annotation prefix
            }
        }
        try {
            factory.bindPropertiesToTarget(); //===> bind properties
        }

谢谢

【问题讨论】:

    标签: java spring yaml properties-file


    【解决方案1】:
    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    yaml.setResources(new ClassPathResource("application.yml"));
    configProperty = yaml.getObject();
    Set<Object> keys = configProperty.keySet();
    

    以下是我的 YAML 配置,如下所示:

    template:
      config:
        broker-urls:
        - tcp://127.0.0.1:61616
        - tcp://127.0.0.1:61617
        - tcp://127.0.0.1:61618
        qeues:
        - Test
        - Demo
        - Qeue3
    

    应用上述代码后,您将获得如下转换后的属性:

    template.config.broker-urls[0]=tcp://127.0.0.1:61616
    template.config.broker-urls[1]=tcp://127.0.0.1:61617
    template.config.broker-urls[1]=tcp://127.0.0.1:61618
    
    template.config.qeues[0]=Test
    template.config.qeues[1]=Demo
    template.config.qeues[1]=Qeue3
    

    【讨论】:

      猜你喜欢
      • 2021-08-16
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-11-29
      • 2014-02-02
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      相关资源
      最近更新 更多