I have a spring boot application where properties have to be read from a yaml file.
code:
@Component
@PropertySource(\"classpath:application.yml\")
p
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.
You can read the value by:
@Value("${app.max.size}")
private String size;
public String getValue(String key) {
return size;
}
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