当前位置: 首页 > 知识库问答 >
问题:

不使用注释或xml读取带前缀的合格yaml文件

毛德曜
2023-03-14

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

然而,在我的情况下,我希望在生命周期的早期完成这一阅读,即在BeanFactoryPostProcessor挂接的时候,以便使用yml中指定的指令动态创建多个bean。

我可以和application.properties合作但不能和application.yml

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

下面是一个如何读取应用程序的示例。属性。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
        }

谢啦

共有1个答案

谢叶五
2023-03-14
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
 类似资料:
  • 我想在Spring Batch中将一个JobParameter传递给我的PoiItemReader,以定位ExcelFilePath。所以我必须使用注释 作业启动时没有异常,但读取器不读取ExcelFile。 我有来自https://github.com/mdeinum/spring-batch-extensions 的PoiItemReader。代码来自教程:https://www.petrik

  • 我试图在没有xml/yaml文件的情况下使用Spring Boot运行Hazelcast客户端应用程序,但我找不到通过Spring管理我的Hazelcast实例的方法。这是我的代码: 当我尝试将hazelcast实例自动关联到主类时,我得到 主要类别代码:

  • 主要内容:注释的特点既然对YAML的语法和基础知识感到满意,那么进一步了解它的细节。在本章中,将了解如何在YAML中使用注释。 YAML支持单行注释。 下面借助一个例子来解释其结构 - YAML不支持多行注释。 如果要为多行提供注释,可以执行此操作,如下例所示 - 注释的特点 YAML中评论的特征如下 - 执行期间会跳过注释的块。 注释有助于添加指定代码块的描述。 注释不得出现在标量内。 YAML不包含任何方法来逃避

  • 有没有办法从一个巨大的xml文件中删除注释( 两者,根元素前的注释 和内的注释 最好的解决方案是使用xPath。我试过了 它适用于DOM,但不适用于vtd xml 这是我选择评论的代码 但此处的屏幕上打印的是nothing。 有没有办法用vtd xml做到这一点? 谢谢你的帮助。

  • 问题内容: 我有一个yaml文件,看起来像这样: 有没有一种方法,我可以和这个数据,同时保持有何评论? 问题答案: PyYAML丢弃了非常低的注释(以中)。 尽管您可以调整或扩展它以处理整个堆栈中的注释,但这将是一个重大修改。发出(=发出)注释似乎更容易,并且在旧的PyYAML错误跟踪器的故障单114中对此进行了讨论。 截至2020年,有关增加对加载评论的支持的功能请求仍处于停滞状态。

  • 在阅读了Oracle论坛,Stackoverflow上有关此内容的所有帖子后,java.net 我终于在这里发布。我正在使用 JAXB 创建 XML 文件,但问题是它在我的元素之前添加了著名的 ns2 前缀,我已经尝试了所有没有人为我工作的解决方案。java 版本给出“1.6.0_37” 解决方案 1:使用包信息.java 我在包含@Xml*注释类的包中创建了文件,内容如下: 解决方案2:Name