【问题标题】:Loading application.properties file to java.util.Properties in Spring Boot在 Spring Boot 中将 application.properties 文件加载到 java.util.Properties
【发布时间】:2017-01-26 17:12:43
【问题描述】:

我通读了 externalized configuration 的 Spring Boot 文档,发现它会自动加载 src/main/resources/application.properties 文件,然后可以使用注释将其连接到 bean 属性。

但是我想要一个通用的PropertyHelper 类,它可以用来构建java.util.Properties 与application.properties 中的属性。这个可以吗?

我们目前正在手动实现这一点,如下所示:

public class PropertyHelper {

    private static Properties loadProperties() {
        try {

             String propsName = "application.properties";
             InputStream propsStream = PropertyHelper.class
                    .getClassLoader().getResourceAsStream(propsName);
            if (propsStream == null) {
                throw new IOException("Could not read config properties");
            }

            Properties props = new Properties();
            props.load(propsStream);

【问题讨论】:

  • application.properties前加一个斜线
  • 或者你可以自动装配环境,它是一个包含文件中所有值的属性类型 bean
  • 使用Environment,您可以获取属性,但它没有所有属性的列表。只能使用env.getProperty("propertyName")获取属性
  • 对于这可以做到吗?,你的实验结果是什么?
  • 但是,Environment 很可能是 ConfigurableEnvironment,它允许您迭代属性源,并且您可以迭代任何 PropertySource 的属性是EnumerablePropertySource。 --- 使用Environment 的好处是您可以获得对 Profiles 和 YAML 等功能的支持。但问题是:为什么需要迭代它们?您不知道您感兴趣的房产名称吗?

标签: spring-boot


【解决方案1】:

您可以在 Environment 周围创建一个Wrapper,这将返回一个现成可用的PropertySource

你会这样使用它:

@PropertySource(name="myName", value="classpath:/myName.properties")
public class YourService {

    @Autowired
    private CustomMapProperties customMapProperties;
    ...
    MapPropertySource mapPropertySource = customMapProperties.getMapProperties("myName");
    for(String key: mapPropertySource.getSource().keySet()){
        System.out.println(mapPropertySource.getProperty(key));
    }

CustomMapProperties 注入Environment 并根据其名称返回请求和加载的属性文件:

@Component
public class CustomMapProperties {

    @Autowired
    private Environment env;

    public MapPropertySource getMapProperties(String name) {
        for (Iterator<?> it = ((AbstractEnvironment) env).getPropertySources().iterator(); it.hasNext();) {
            Object propertySource = it.next();
            if (propertySource instanceof MapPropertySource
                    && ((MapPropertySource) propertySource).getName().equals(name)) {
                return (MapPropertySource) propertySource;
            }
        }
        return null;
    }
}

【讨论】:

    【解决方案2】:

    下面是我从 Spring 的 Environment 派生 Properties 对象的方法。我寻找 java.util.Properties 类型的属性源,在我的情况下,它将给我系统属性和应用程序属性。

    @Resource
    private Environment environment;
    
    
    @Bean
    public Properties properties() {
        Properties properties = new Properties();
    
        for (PropertySource<?> source : ((ConfigurableEnvironment) environment).getPropertySources()) {
            if (source.getSource() instanceof Properties) {
                log.info("Loading properties from property source " + source.getName());
                Properties props = (Properties) source.getSource();
                properties.putAll(props);
            }
        }
    
        return properties;
    }
    

    但请注意,订单可能很重要;您可能希望在其他属性之后加载系统属性,以便它们可以覆盖应用程序属性。在这种情况下,使用source.getName() 添加更多控制代码来选择“systemProperties”:

    @Bean
    public Properties properties() {
        Properties properties = new Properties();
    
        Properties systemProperties = null;
    
        for (PropertySource<?> source : ((ConfigurableEnvironment) environment).getPropertySources()) {
            if (source.getSource() instanceof Properties) {
                if ("systemProperties".equalsIgnoreCase(source.getName())) {
                    log.info("Found system properties from property source " + source.getName());
                    systemProperties = (Properties) source.getSource();
                } else {
                    log.info("Loading properties from property source " + source.getName());
                    Properties props = (Properties) source.getSource();
                    properties.putAll(props);
                }
            }
        }
    
        // Load this at the end so they can override application properties.
        if (systemProperties != null) {
            log.info("Loading system properties from property source.");
            properties.putAll(systemProperties);
        }
    
        return properties;
    }
    

    【讨论】:

      【解决方案3】:

      在构造函数中注入应用程序上下文参数并将其传递到 java.util.properties:

      import java.util.Properties;
      import org.springframework.boot.ApplicationArguments;
      
      public MyComponentClass(ApplicationArguments arguments) {
      
        Properties properties = getProperties(arguments);
      }
      
      private static Properties getProperties(ApplicationArguments arguments) {
      
        Properties properties = new Properties();
      
        for (String argementName : arguments.getOptionNames()) {
      
          List<String> argumentValues = arguments.getOptionValues(argementName);
      
          if (argumentValues.size() > 0) {
            properties.put(argementName, argumentValues.get(0));
          }
        }
      
        return properties;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-04
        • 2020-09-07
        • 1970-01-01
        • 2012-02-02
        • 2014-12-17
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        相关资源
        最近更新 更多