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.
Propriedades com Spring e Spring Boot
Tutorial de como trabalhar com arquivos de propriedades e valores de propriedades no Spring.
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:
-
Parâmetro de contexto emweb.xml
-
WebApplicationInitializer
-
Parâmetro do Sistema JVM
-
Variável de ambiente
-
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á.