袁文涛
袁文涛

Reputation: 856

How to read config file (*.yaml *.properties) without spring framework

I have a project but not in spring, how can I use annotation to read content in config files like *.yaml or *.properties under resource package.

Upvotes: 16

Views: 24440

Answers (3)

Faraz
Faraz

Reputation: 6265

You can use SnakeYAML without Spring.

Download the dependency:

compile group: 'org.yaml', name: 'snakeyaml', version: '1.24'

Then you can load the .yaml (or .yml) file this way:

Yaml yaml = new Yaml();
InputStream inputStream = this.getClass().getClassLoader()
                           .getResourceAsStream("youryamlfile.yaml"); //This assumes that youryamlfile.yaml is on the classpath
Map<String, Object> obj = yaml.load(inputStream);
obj.forEach((key,value) -> { System.out.println("key: " + key + " value: " + value ); });

Reference.

Edit: Upon further investigation, OP wants to know how to load properties in Spring boot. Spring boot has a built-in feature to read properties.

Let's say you have a application.properties sitting in src/main/resources, and in it there is an entry say application.name="My Spring Boot Application", then in one of your classes annotated with @Component or any of its sub-stereotype annotations, one can fetch values like this:

@Value("${application.name}")
private String applicationName;

The property in application.property file is bound now to this variable applicationName

You could also have a application.yml file and have the same property written this way

application:
  name: "My Spring Boot Application"

You will get this property value the same way like last time by annotation a filed with @Value annotation.

Upvotes: 19

Mykhaylo Adamovych
Mykhaylo Adamovych

Reputation: 20956

flat properties from yaml

import static java.lang.String.format;
import static java.lang.System.getenv;
import static java.nio.charset.Charset.defaultCharset;
import static java.util.Collections.singletonMap;
import static org.apache.commons.io.IOUtils.resourceToString;
import static org.apache.commons.lang3.StringUtils.isBlank;

import java.io.IOException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.yaml.snakeyaml.Yaml;

public class PropertiesUtils {

    public static Properties loadProperties() {
        return loadProperties(getenv("ENV"));
    }

    public static Properties loadProperties(String profile) {
        try {
            Yaml yaml = new Yaml();
            Properties properties = new Properties();
            properties.putAll(getFlattenedMap(yaml.load(resourceToString("/application-config.yml", defaultCharset()))));
            if (profile != null)
                properties.putAll(getFlattenedMap(yaml.load(resourceToString(format("/application-config-%s.yml", profile), defaultCharset()))));
            return properties;
        } catch (IOException e) {
            throw new Error("Cannot load properties", e);
        }
    }

    private static final Map<String, Object> getFlattenedMap(Map<String, Object> source) {
        Map<String, Object> result = new LinkedHashMap<>();
        buildFlattenedMap(result, source, null);
        return result;
    }

    @SuppressWarnings("unchecked")
    private static void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
        source.forEach((key, value) -> {
            if (!isBlank(path))
                key = path + (key.startsWith("[") ? key : '.' + key);
            if (value instanceof String) {
                result.put(key, value);
            } else if (value instanceof Map) {
                buildFlattenedMap(result, (Map<String, Object>) value, key);
            } else if (value instanceof Collection) {
                int count = 0;
                for (Object object : (Collection<?>) value)
                    buildFlattenedMap(result, singletonMap("[" + (count++) + "]", object), key);
            } else {
                result.put(key, value != null ? "" + value : "");
            }
        });
    }
}

Upvotes: 3

Suketu Bhuta
Suketu Bhuta

Reputation: 2023

I understand your question is about accessing the content with .yaml and .properties file without using the Spring framework, however if you do have access to the Spring Framework in your classpath and don't mind using some internal classes, the following code can read the content in a very succinct fashion

For Properties file:

    File file = ResourceUtils.getFile("classpath:application.properties");
    PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
    propertiesFactoryBean.setLocation(new PathResource(file.toPath()));
    propertiesFactoryBean.afterPropertiesSet();

    // you now have properties corresponding to contents in the application.properties file in a java.util.Properties object
    Properties applicationProperties = propertiesFactoryBean.getObject();   
    // now get access to whatever property exists in your file, for example
    String applicationName = applicationProperties.getProperty("spring.application.name"); 

For a Yaml resource

    File file = ResourceUtils.getFile("classpath:application.yaml");
    YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
    factory.setResources(new PathResource(file.toPath()));
    factory.afterPropertiesSet();

    // you now have properties corresponding to contents in the application.yaml file in a java.util.Properties object
    Properties applicationProperties = factory.getObject();
    // now get access to whatever property exists in your file, for example
    String applicationName = applicationProperties.getProperty("spring.application.name"); 

Upvotes: 2

Related Questions