Perfis de molas

Perfis de molas

1. Visão geral

Neste artigo, vamos nos concentrar na introdução deProfiles in Spring.

Perfis são um recurso central do framework - permitindo-nos mapear nossos beans para diferentes perfis - por exemplo,dev,test,prod.

Podemos então ativar perfis diferentes em ambientes diferentes para inicializar apenas os beans necessários:

Leitura adicional:

Configurando o DataSource separado da Spring para testes

Um tutorial rápido e prático sobre como configurar uma fonte de dados separada para teste em um aplicativo Spring.

Read more

Propriedades com Spring e Spring Boot

Tutorial de como trabalhar com arquivos de propriedades e valores de propriedades no Spring.

Read more

2. Use@Profile em um Bean

Vamos começar de forma simples e ver como podemos fazer um bean pertencer a um determinado perfil. Usando a anotação@Profile - estamos mapeando o bean para aquele perfil particular; a anotação simplesmente leva os nomes de um (ou vários) perfis.

Considere um cenário básico - temos um bean que só deve estar ativo durante o desenvolvimento, mas não implementado na produção. Anotamos esse bean com um perfil “dev” e ele só estará presente no contêiner durante o desenvolvimento - na produção, odev simplesmente não estará ativo:

@Component
@Profile("dev")
public class DevDatasourceConfig

Como uma rápida nota lateral, os nomes de perfis também podem ser prefixados com um operador NOT, por exemplo “!dev” para excluí-los de um perfil.

No exemplo abaixo, o componente é ativado apenas se o perfil “dev” não estiver ativo:

@Component
@Profile("!dev")
public class DevDatasourceConfig

3. Declarar perfis em XML

Os perfis também podem ser configurados em XML - a tag<beans> tem o atributo“profiles” que leva valores separados por vírgula dos perfis aplicáveis:


    

4. Definir perfis

A próxima etapa é ativar e definir os perfis para que os respectivos beans sejam registrados no contêiner.

Isso pode ser feito de várias maneiras - que exploraremos nas seções a seguir.

4.1. Programaticamente via interfaceWebApplicationInitializer

Em aplicativos da web,WebApplicationInitializer pode ser usado para configurarServletContext programaticamente.

Também é um local muito útil para definir nossos perfis ativos de forma programática:

@Configuration
public class MyWebApplicationInitializer
  implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        servletContext.setInitParameter(
          "spring.profiles.active", "dev");
    }
}

4.2. Programaticamente por meio deConfigurableEnvironment

Você também pode definir perfis diretamente no ambiente:

@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");

4.3. Parâmetro de contexto emweb.xml

Da mesma forma,profiles can be activated in the web.xml do aplicativo da web também, usando um parâmetro de contexto:


    contextConfigLocation
    /WEB-INF/app-config.xml


    spring.profiles.active
    dev

4.4. Parâmetro do sistema JVM

Os nomes do perfil também podem ser transmitidos por meio de um parâmetro do sistema JVM. Os nomes de perfil passados ​​como o parâmetro serão ativados durante a inicialização do aplicativo:

-Dspring.profiles.active=dev

4.5. Variável de ambiente

Em um ambiente Unix,profiles can also be activated via the environment variable:

export spring_profiles_active=dev

4.6. Perfil do Maven

Os perfis Spring também podem ser ativados por meio de perfis Maven, especificando a propriedade de configuraçãospring.profiles.active .

Em cada perfil Maven, podemos definir uma propriedadespring.profiles.active:


    
        dev
        
            true
        
        
            dev
        
    
    
        prod
        
            prod
        
    

Seu valor será usado para substituir o marcador@[email protected] emapplication.properties:

[email protected]@

Agora, precisamos habilitar a filtragem de recursos empom.xml:


    
        
            src/main/resources
            true
        
    
    ...

E anexe um parâmetro-P para alternar qual perfil Maven será aplicado:

mvn clean package -Pprod

Este comando irá empacotar o aplicativo para o perfilprod. Ele também aplica ospring.profiles.active value‘prod' para este aplicativo quando ele está em execução.

4.7. @ActiveProfile em testes

Os testes tornam muito fácil especificar quais perfis estão ativos - usando a anotação@ActiveProfile para habilitar perfis específicos:

@ActiveProfiles("dev")

Para resumir, examinamos várias maneiras de ativar perfis. Vamos agora ver qual tem prioridade sobre o outro e o que acontece se você usar mais de um - da maior para a menor prioridade:

  1. Parâmetro de contexto emweb.xml

  2. WebApplicationInitializer

  3. Parâmetro do Sistema JVM

  4. Variável de ambiente

  5. Perfil do Maven

5. O Perfil Padrão

Qualquer bean que não especifica um perfil pertence ao perfil “default”.

O Spring também fornece uma maneira de definir o perfil padrão quando nenhum outro perfil está ativo - usando a propriedade “spring.profiles.default”.

6. Obtenha perfis ativos

Os perfis ativos do Spring conduzem o comportamento da anotação@Profile para habilitar / desabilitar beans. No entanto, também podemos desejar acessar a lista de perfis ativos programaticamente.

Temos duas maneiras de fazer isso,using Environment or*spring.active.profile*.

6.1. UsandoEnvironment

Podemos acessar os perfis ativos do objetoEnvironment injetando-o:

public class ProfileManager {
    @Autowired
    private Environment environment;

    public void getActiveProfiles() {
        for (String profileName : environment.getActiveProfiles()) {
            System.out.println("Currently active profile - " + profileName);
        }  
    }
}

6.2. Usandospring.active.profile

Alternativamente, poderíamos acessar os perfis injetando a propriedadespring.profiles.active:

@Value("${spring.profiles.active}")
private String activeProfile;

Aqui, nossa variávelactiveProfilewill contain the name of the profile that is currently active, e se houver várias, conterá seus nomes separados por uma vírgula.

No entanto, devemosconsider what would happen if there is no active profile at all. Com o código acima, a ausência de um perfil ativo impediria a criação do contexto do aplicativo. Isso resultaria em umIllegalArgumentException devido ao espaço reservado ausente para injetar na variável.

Para evitar isso, podemosdefine a default value:

@Value("${spring.profiles.active:}")
private String activeProfile;

Agora, se nenhum perfil estiver ativo, nossoactiveProfile conterá apenas uma string vazia. E, se quisermos acessar a lista deles exatamente como no exemplo anterior, podemos fazer isso porsplittinga variávelactiveProfile:

public class ProfileManager {
    @Value("${spring.profiles.active:}")
    private String activeProfiles;

    public String getActiveProfiles() {
        for (String profileName : activeProfiles.split(",")) {
            System.out.println("Currently active profile - " + profileName);
        }
    }
}

7. Exemplo de uso de perfis

Agora que o básico está fora do caminho, vamos dar uma olhada em um exemplo real.

Considere um cenário em que precisamos manter a configuração da fonte de dados para os ambientes de desenvolvimento e produção. Vamos criar uma interface comumDatasourceConfig que precisa ser implementada por ambas as implementações de fonte de dados:

public interface DatasourceConfig {
    public void setup();
}

A seguir, está a configuração para o ambiente de desenvolvimento:

@Component
@Profile("dev")
public class DevDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
        System.out.println("Setting up datasource for DEV environment. ");
    }
}

E configuração para o ambiente de produção:

@Component
@Profile("production")
public class ProductionDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
       System.out.println("Setting up datasource for PRODUCTION environment. ");
    }
}

Agora vamos criar um teste e injetar nossa interface DatasourceConfig; dependendo do perfil ativo, o Spring injetaráDevDatasourceConfig ouProductionDatasourceConfig bean:

public class SpringProfilesWithMavenPropertiesIntegrationTest {
    @Autowired
    DatasourceConfig datasourceConfig;

    public void setupDatasource() {
        datasourceConfig.setup();
    }
}

Quando o perfil “dev” está ativo, a mola injeta o objetoDevDatasourceConfig e, na chamada do métodosetup(), o seguinte é a saída:

Setting up datasource for DEV environment.

8. Perfis no Spring Boot

O Spring Boot suporta toda a configuração de perfil descrita até o momento, com alguns recursos adicionais.

O parâmetro de inicializaçãospring.profiles.active, apresentado na seção 4, também pode ser configurado como uma propriedade no Spring Boot para definir os perfis atualmente ativos. Esta é uma propriedade padrão que o Spring Boot selecionará automaticamente:

spring.profiles.active=dev

Para definir perfis de forma programática, também podemos usar a classeSpringApplication:

SpringApplication.setAdditionalProfiles("dev");

Para definir perfis usando Maven no Spring Boot, podemos especificar nomes de perfil emspring-boot-maven-plugin empom.xml:


    
        org.springframework.boot
        spring-boot-maven-plugin
        
            
                dev
            
        
    
    ...

E execute o objetivo Maven específico do Spring Boot:

mvn spring-boot:run

Mas o recurso relacionado a perfis mais importante que o Spring Boot traz éprofile-specific properties files. Eles devem ser nomeados no formatoapplications-{profile}.properties.

O Spring Boot carregará automaticamente as propriedades em um arquivoapplication.properties para todos os perfis, e aquelas em arquivos.properties específicos de perfil apenas para o perfil especificado.

Por exemplo, podemos configurar diferentes fontes de dados para os perfisdeveproduction usando dois arquivos chamadosapplication-dev.propertieseapplication-production.properties:

No arquivoapplication-production.properties, podemos configurar uma fonte de dadosMySql:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=root
spring.datasource.password=root

Em seguida, podemos configurar as mesmas propriedades para o perfildev no arquivoapplication-dev.properties, para usar um banco de dadosH2 na memória:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

Dessa forma, podemos facilmente fornecer configurações diferentes para ambientes diferentes.

9. Conclusão

Neste tutorial rápido, discutimos comodefine a profile em um bean e como entãoenable the right profiles em nosso aplicativo.

Por fim, validamos nossa compreensão de perfis com um exemplo simples, mas ainda do mundo real.

A implementação deste tutorial REST do Spring Security pode ser encontrada emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.