Tengo el código que analiza el contexto de primavera:
public void scan() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(SomeConfig.class);
context.refresh();
}
Necesito propiedades para ser leído de application.yml
archivo, por lo que en SomeConfig
la clase, tengo esto:
@Configuration
@PropertySource(value = "classpath:application.yml", factory = YamlPropertyLoaderFactory.class)
public class SomeConfig {
//some beans
}
(He copiado YamlPropertyLoaderFactory clase a partir de aquí )
application.yml
es un archivo típico de primavera de arranque con algunas propiedades de perfil, y un perfil predeterminado:
spring:
profiles:
active: p1
---
spring:
profiles: p1
file: file1.txt
---
spring:
profiles: p2
file: file2.txt
En algunos frijol, estoy leyendo file
establecimiento utilizando @Value
.
Cuando ejecuto mi aplicación, Estoy de paso -Dspring.profiles.active=p1
variable, pero estoy consiguiendo un error:
No se pudo resolver marcador de posición 'archivo' en el valor "$ {} archivo"
(Se debe trabajar incluso si no pasar cualquier perfil desde application.yml tiene establecido el perfil predeterminado a p1)
Si quito todos los perfiles config application.yml
, que funciona bien:
file: file1.txt
Por lo tanto, esto significa que la exploración contexto no está leyendo la variable de perfil.
También, si fijo perfil activo "programáticamente", no resuelve las propiedades ya sea:
context.getEnvironment().setActiveProfiles("p1");
El YamlPropertyLoaderFactory
que se refieren a tiene el siguiente código:
public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null){
return super.createPropertySource(name, resource);
}
return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), null);
}
}
El tercer parámetro para el YamlPropertySourceLoader.load()
método es en realidad el nombre del perfil que desea para las propiedades. Como este ejemplo pasa nula simplemente devuelve el conjunto de propiedades del archivo de yml no para un perfil específico.
es decir
spring:
profiles:
active: p1
---
No creo que sea fácil de recoger el nombre del perfil activo en el YamlPropertyLoaderFactory
, aunque se podría intentar algo así como ...
public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null){
return super.createPropertySource(name, resource);
}
String activeProfile = System.getProperty("spring.profiles.active");
return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), activeProfile);
}
}
O como usted tiene el nombre del perfil activo en el archivo yml, se podría llamar YamlPropertySourceLoader().load
con nula para obtener la propiedad spring.profiles.active luego llamar de nuevo para cargar la parte real del archivo yml desea.
public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null){
return super.createPropertySource(name, resource);
}
PropertySource<?> source = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), null);
String activeProfile = source.getProperty("spring.profiles.active");
return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), activeProfile);
}
}
YamlPropertySourceLoader
fue cambiado de nuevo en febrero de 2018 ( Ver culpa YamlPropertySourceLoader en Git repo ). Ahora se devuelve una lista de propertySource y no tiene el tercer parámetro del método de carga.
Siempre y cuando tenga la propiedad spring.profiles.active en el archivo yml que sería capaz de hacer lo siguiente con la versión más reciente de YamlPropertySourceLoader
public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null){
return super.createPropertySource(name, resource);
}
List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
for (PropertySource<?> checkSource : sources) {
if (checkSource.containsProperty("spring.profiles.active")) {
String activeProfile = (String) checkSource.getProperty("spring.profiles.active");
for (PropertySource<?> source : sources) {
if (activeProfile.trim().equals(source.getProperty("spring.profiles"))) {
return source;
}
}
}
}
return sources.get(0);
}
}