1. Introducción

Hola a todos y bienvenidos de nuevo!.

En este post veremos como hacer uso de los perfiles de Spring cuando arrancamos un microservicio. La finalidad principal es disponer de diferentes configuraciones de una forma rápida y sencilla de tal forma que podamos:

  • Configurar el contexto de Spring en función del perfil
  • Obtención de ficheros de propiedades en función del perfil

Configurar el contexto de Spring en función del perfil
La idea principal es poder definir unos beans u otros en el contexto de Spring. Para ello haremos uso de la anotación @Profile que pone a nuestra disposición Spring 4. Podemos utilizarlo a nivel de:

1. Servicio

@Profile("local")
@Service
public class MiServicio implementes IMiServicio{
   ...
}

2. Configuración

@Profile("local")
@Configuration
public class MiConfiguration{
   ...
}

3. Bean

@Configuration
public class MiConfiguration{
   ...
   @Profile("local")
   @Bean
   public IMiBean buildMiBean(){
      return new MiBean();
   }
   ...
}

Obtención de ficheros de propiedades en función del perfil
Como comentamos en el post Property, el fichero de propiedades que se carga en Spring Boot se debe encontrar en la raiz de nuestro classpath con el nombre application.yml. Sin embargo si arrancamos nuestro Spring Boot con un perfil, se obtendrán las propiedades de:

  • application-[PERFIL].yml
  • application.yml

Hay que tener en cuenta que en el caso de existir propiedades compartidas en ambos ficheros, tendrán preferencia las definidas en el fichero application-[PERFIL].yml sobre las definidas en applicacion.yml.

Como arrancar nuestros microservicios con un perfil
Basta con añadir la siguiente propiedad en el arranque de la aplicación

--spring.profiles.active=[PERFIL]

Os podéis descargar el código de ejemplo de mi GitHub aquí.

Tecnologías empleadas:

  • Java 8
  • Gradle 3.1
  • SpringBoot 1.5.2.RELEASE
  • Spring 4.3.7.RELEASE

2. Ficheros

Añadimos la dependencia la dependencia org.springframework.boot:spring-boot-starter-web de SpringBoot.

group 'com.jorgehernandezramirez.spring.springboot'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'maven'

sourceCompatibility = 1.8

springBoot {
    mainClass = "com.jorgehernandezramirez.spring.springboot.profile.Application"
}

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
}

Se muestra a continuación los ficheros application.yml y application-local.yml. En caso de cargar el perfil local, las propiedades que encontremos en el fichero application-local.yml tendrán preferencia sobre las que se encuentran en application.yml

server:
  port: 8080

mongodb:
  url: mongodburl
  version: 3.4
mongodb:
  url: localmongodburl

Main que arranca SpringBoot

package com.jorgehernandezramirez.spring.springboot.profile;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public Application(){
        //For Spring
    }

    public static void main(String[] parameters){
        SpringApplication.run(Application.class, parameters);
    }
}

Mostramos la api IProperties que se encargará de proporcionarnos algunas propiedades.

package com.jorgehernandezramirez.spring.springboot.profile.service;

/*
  API de gestión de properties
*/
public interface IProperties {

    /**
     * Método que devuelve el valor de la url de mongodb definido en los
     * properties
     * @return
     */
    String getPropertyMongoDbUrl();

    /**
     * Método que devuelve el valor de la version de mongodb definido en los
     * properties
     * @return
     */
    String getPropertyMongoDbVersion();
}

Mostramos la implementación PropertiesImpl que se debe cargar en el contexto cuando no existe el perfil local.

package com.jorgehernandezramirez.spring.springboot.profile.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Profile("!local")
@Service
public class PropertiesImpl implements IProperties{

    @Value("${mongodb.url}")
    private String mongoDBUrl;

    @Value("${mongodb.version}")
    private String mongodbVersion;

    public PropertiesImpl(){
        //Para Spring
    }

    @Override
    public String getPropertyMongoDbUrl() {
        return mongoDBUrl;
    }

    @Override
    public String getPropertyMongoDbVersion() {
        return mongodbVersion;
    }
}

Por otro lado se muestra la implementación ProfileLocalPropertiesImpl.java que se debe cargar en el contexto cuando arrancamos la aplicación con el perfil local.

package com.jorgehernandezramirez.spring.springboot.profile.service;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Profile("local")
@Service
public class ProfileLocalPropertiesImpl extends PropertiesImpl{

    public ProfileLocalPropertiesImpl(){
        //Para Spring
    }
}

Controlador de test

package com.jorgehernandezramirez.spring.springboot.profile.controller;

import com.jorgehernandezramirez.spring.springboot.profile.service.IProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PropertyController {

    @Autowired
    private IProperties properties;

    public PropertyController(){
        //For Spring
    }

    @RequestMapping(value = "/mongodb/url")
    public String getPropertyMongoDbUrl() {
        return properties.getPropertyMongoDbUrl();
    }

    @RequestMapping(value = "/mongodb/version")
    public String getPropertyMongoDbVersion() {
        return properties.getPropertyMongoDbVersion();
    }
}

3. Probando la aplicación

Compilamos los fuentes

gradle clean install

Arrancamos la aplicación sin ningún perfil

java -jar SpringBootProfile-1.0-SNAPSHOT.jar

Llamamos al controlador /mongodb/url que nos debe dar la url de mongodb

curl http://localhost:8080/mongodb/url

Obtenemos

mongodburl

Arrancamos la aplicación con el perfil local

java -jar SpringBootProfile-1.0-SNAPSHOT.jar --spring.profiles.active=local

Llamamos al controlador /mongodb/url que nos debe dar la url de mongodb en local

curl http://localhost:8080/mongodb/url

Obtenemos

localmongodburl