【问题标题】:Reading entire property file loaded by PropertySource in spring bean在spring bean中读取PropertySource加载的整个属性文件
【发布时间】:2016-06-22 04:37:41
【问题描述】:

我有一个 spring bean,它根据其可用性加载属性文件,如下所示:-

@PropertySources({ @PropertySource(value = "classpath:user.properties"),
@PropertySource(value = "file:./config/user.properties", ignoreResourceNotFound = true) })

属性文件正在加载,但是当我尝试一次读取整个属性文件时:-

Properties properties = PropertiesLoaderUtils.loadAllProperties("user.properties");

然后我只从类路径中获取属性。 spring 是否提供任何机制来一次性读取所有属性?

【问题讨论】:

    标签: java spring properties spring-boot


    【解决方案1】:

    你的代码没有做注释做的事情。您有几个注释来声明要做什么。代码 sn-p 中根本不存在该逻辑。

    没有什么神奇的,如果你想要相同的结果,你需要在代码中翻译这些注释的声明性方面(即读取类路径文件,然后是文件一并检查它是否存在,然后合并这些属性)。

    如果您可以获取额外的密钥,您也可以简单地注入 Environment,因为 @PropertySource 将更新它。

    【讨论】:

    • 好的,有什么方法可以从注入到 Resource 对象(由 spring 提供)中的文件中获取所有属性?
    【解决方案2】:

    回答我自己的问题,这可能会对某人有所帮助。 由于我需要使用外部属性文件(如果存在于指定文件夹中)覆盖 jar 中包含的属性文件,因此我还需要一次性读取整个属性文件。 我已经利用加载最后一个属性读取的弹簧行为。

    @PropertySources({ @PropertySource(value = "classpath:application.properties"),
    @PropertySource(value = "file:./config/application.properties", ignoreResourceNotFound = true) })
    

    现在如果 application.properties 存在于 ./config/ 位置,那么它将覆盖类路径中的 application.properties。

    在主 application.properties 中,我定义了应该从哪里加载外部属性,即

    config.location=./config/
    

    ./config/ 属性可以在生产和测试环境中被覆盖。

    在此之后,我定义了一个 bean 来加载所有属性文件(跳过导入语句):-

    @Component
    public class PropertiesConfig {
    
    private final Logger logger = LoggerFactory.getLogger(PropertiesConfig.class);
    
    private final String[] PROPERTIES_FILENAMES = { "prop1.properties", "prop2.properties",
        "prop3.properties" };
    
    private String configLocation;
    
    private Map<String, Properties> configProperties;
    
    @Autowired
    public PropertiesConfig(@Value("${config.location}") String configLocation) {
    this.configLocation = configLocation;
    configProperties = Arrays.stream(PROPERTIES_FILENAMES)
        .collect(Collectors.toMap(filename -> filename, this::loadProperties));
    }
    
    public Properties getProperties(String fileName) {
    
    if (StringUtils.isEmpty(fileName) || !configProperties.containsKey(fileName)) {
        logger.info(String.format("Invalid property name : %s", fileName));
        throw new IllegalArgumentException(
            String.format("Invalid property name : %s", fileName));
    }
    return configProperties.get(fileName);
    }
    
    private Properties loadProperties(final String filename) {
    final Resource[] possiblePropertiesResources = { new ClassPathResource(filename),
        new PathResource(getCustomPath(filename)) };
    final Resource resource = Arrays.stream(possiblePropertiesResources)
        .filter(Resource::exists).reduce((previous, current) -> current).get();
    final Properties properties = new Properties();
    
    try {
        properties.load(resource.getInputStream());
    } catch (final IOException exception) {
        throw new RuntimeException(exception);
    }
    
    logger.info("Using {} as user resource", resource);
    
    return properties;
    }
    
      private String getCustomPath(final String filename) {
        return configLocation.endsWith(".properties") ? configLocation :                configLocation + filename;
       }
       }
    

    现在你有了一个包含 map 中所有属性文件的 bean,它可以注入任何 bean 并且可以在任何环境中被覆盖。

    【讨论】:

      猜你喜欢
      • 2018-02-15
      • 2019-03-04
      • 2016-07-20
      • 2018-05-24
      • 2018-01-05
      • 2023-03-12
      • 2013-05-26
      • 2016-03-29
      • 2010-12-08
      相关资源
      最近更新 更多