spring boot read properties from yml file

后端 未结 3 1511
再見小時候
再見小時候 2020-12-22 01:00

I have a spring boot application where properties have to be read from a yaml file.

code:

@Component
@PropertySource(\"classpath:application.yml\")
p         


        
相关标签:
3条回答
  • 2020-12-22 01:24

    Since you'r using application.yml file, you don't need to manually load the file to the context as it's the default config file for spring application. You can simply use them in a @Component decorated class like below;

    @Value("${app.max.size}")
    private int size;
    

    If you're laoding custom YAML file, then this is a huge problem in Spring yet. Using @PropertySource you can't load YAML files simply. It's possible, but little work required. First you need a custom property source factory. In your case, custom YAML property source factory.

    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;
    
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.Objects;
    import java.util.Properties;
    
    public class YamlPropertySourceFactory implements PropertySourceFactory {
    
        /**
         * Create a {@link PropertySource} that wraps the given resource.
         *
         * @param name     the name of the property source
         * @param resource the resource (potentially encoded) to wrap
         * @return the new {@link PropertySource} (never {@code null})
         * @throws IOException if resource resolution failed
         */
        @Override
        public PropertySource<?> createPropertySource(String name, EncodedResource resource)
                throws IOException {
            Properties properties = load(resource);
            return new PropertiesPropertySource(name != null ? name :
                    Objects.requireNonNull(resource.getResource().getFilename(), "Some error message"),
                    properties);
        }
    
        /**
         * Load properties from the YAML file.
         *
         * @param resource Instance of {@link EncodedResource}
         * @return instance of properties
         */
        private Properties load(EncodedResource resource) throws FileNotFoundException {
            try {
                YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
                factory.setResources(resource.getResource());
                factory.afterPropertiesSet();
    
                return factory.getObject();
            } catch (IllegalStateException ex) {
                /*
                 * Ignore resource not found.
                 */
                Throwable cause = ex.getCause();
                if (cause instanceof FileNotFoundException) throw (FileNotFoundException) cause;
                throw ex;
            }
        }
    }
    

    And, you need to tell @PropertySource annotation use this factory instead of default one whenever you use it like below;

    @Component
    @PropertySource(value = "classpath:config-prop.yml", factory = YamlPropertySourceFactory.class) // Note the file name with the extension unlike a property file. Also, it's not the `application.yml` file.
    public class ResourceProvider { 
    
        @Value("${app.max.size}")
        private int size;
    }
    

    You can use your properties shown in above code snippet's size variable.

    Though. If you're using a YAML array declaration to get properties, that would be little peculiar even if you use this way.

    0 讨论(0)
  • 2020-12-22 01:36

    You can read the value by:

    @Value("${app.max.size}")
    private String size;  
    
    public String getValue(String key) {
       return size;
    }
    
    0 讨论(0)
  • 2020-12-22 01:40

    from the documentation:

    YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.

    Official spring boot documentation reference

    0 讨论(0)
提交回复
热议问题