Spring Boot:使用 @ConfigurationProperties 从 yaml 读取对象列表始终返回 null

问题描述 投票:0回答:2

我想创建一个 yaml 文件,从中获取常量

常量配置.yml

constants:
 myList:
   -
     id: 11
     name: foo1
     firstName: bar1
     allowed: true
   -
     id: 22
     name: foo2
     firstName: bar2
     allowed: false

配置类如下所示:

@Data
@Component
@PropertySource("classpath:constantsConfiguration.yml")
@ConfigurationProperties(prefix = "constants")
public class ConstantProperties {

    private List<User> myList;

    @Data
    public static class User{
        private String id;
        private String name;
        private String firstName;
        private Boolean allowed;

    }
}

这是我想如何使用它的一个虚拟示例

@Service
@RequiredArgsConstructor
public class MyService{

   private final ConstantProperties constantProperties;

   public Boolean isEmptyList(){
       return CollectionUtils.isEmpty(constantProperties.getMyList());
   }
}

constantProperties.getMyList()
始终为空 我正在使用 spring boot:2.5.12 和 java 11

java spring-boot yaml
2个回答
4
投票

根本原因是新的SpringBoot不会将properties文件解析为yaml属性。

您需要先添加一个Yaml PropertiesSourceFactory 类。如下:

import java.io.IOException;
import java.util.Properties;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(encodedResource.getResource());

        Properties properties = factory.getObject();

        return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
    }
}

然后在ConstantsProperties类中,需要明确指定Factory类。喜欢:

import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import lombok.Data;

@Data
@Component
@PropertySource(value = "classpath:constantsConfiguration.yml", factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "constants")
public class ConstantProperties {
    private List<User> myList;

    @Data
    public static class User {
        private String id;
        private String name;
        private String firstName;
        private Boolean allowed;

    }

}

最后,请注意您的 yaml 文件格式。 每个分隔符应为 2 个“ ”空白字符。

请尝试一下,现在应该可以了。


0
投票

@SeanH 的回答对我不起作用。我发现让它解析列表的方法是使用地图列表。然后你需要将每个地图转换成你想要的对象:

首先按照 SeanH 的解释创建 YamlPropertySourceFactory,然后在 ConstantProperties.class 中:

@Component
@PropertySource(value = "classpath:constantsConfiguration.yml", factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "constants")
public class ConstantProperties {
    private List<Map<String, String>> myList;

    public List<User> getUserList() {
        List<User> users = new ArrayList<>();
        myList.forEach(userInfo -> {
            User user = new User(userInfo.get("id"),
                                 userInfo.get("name"),
                                 userInfo.get("firstName"),
                                 Boolean.valueOf(userInfo.get("allowed")));
            users.add(user);
        });
        return users;
    }

    public static class User {
        private String id;
        private String name;
        private String firstName;
        private Boolean allowed;

        public User(String id, String name, String firstName, Boolean allowed) {
            this.id=id;
            this.name=name;
            this.firstName=firstName;
            this.allowed=allowed;
        }
    }

© www.soinside.com 2019 - 2024. All rights reserved.