Olá senhores e senhoritas visitantes deste badalado blog javístico! Depois de um longo hiato encontrei tempo e empolgação para fazer um post esperançosamente rápido.

Já tiveram num projeto a necessidade de dinamizar ao máximo possível a definição de configurações da aplicação sem partir para banco de dados ou exigir um monte de variáveis de sistema?

Bem, vou apresentar um padrãozinho que geralmente uso para aplicar no projeto arquivos de configurações de acordo com ambiente ou situações específicas. Essas configurações podem ser usadas para inicializar um datasource do banco, ou para injetar valores num bean do Spring.

Vou assumir um projeto Java com um contexto Spring inicializado.

 

CONFIGURAÇÃO

Assim, vamos direto ao XML (sim! X-M-L!):

O PropertiesFactoryBean criará um properties injetável pelo Spring que será inicializado com os arquivos de propriedades de acordo com a seguinte regra:

  1. Os dados serão obtidos do arquivo env/environment_DEFAULT.properties
  2. Os dados serão obtidos do arquivo classpath:env/environment_${CUSTOM_ENV}.properties, sendo que ${CUSTOM_ENV} será substituído pela variável de sistema CUSTOM_ENV*. Em caso de conflito com propriedades já definidas, o valor será atualizado.
  3. Os dados serão obtidos do arquivo externo ao projeto cujo caminho é dado pela variável de sistema CUSTOM_EXTERNAL_CONFIG*. Em caso de conflito com propriedades já definidas, o valor será atualizado.

 

* Essa variável poderá ser declarada como variável de ambiente do sistema operacional (set CUSTOM_ENV = …) ou variável do Java ( -DCUSTOM_ENV=… ).

Assim, o projeto poderá conter um arquivo environment_DEFAULT.properties com configurações de desenvolvimento; e poderá ter um environment_PRODUCTION.properties com configurações de produção a serem usadas no servidor com a variável de ambiente CUSTOM_ENV=”PRODUCTION”.

Além disso, caso sejam necessárias configurações muito específicas sem precisar recompilar o projeto, pode-se usar um arquivo externo cujo caminho seja passado pela variável de sistema CUSTOM_EXTERNAL_CONFIG. Ex: -DCUSTOM_EXTERNAL_CONFIG=/home/custom.properties.

 

USO

Para injetar valores em atributos de algum bean do Spring é bem simples. Considerando o arquivo env/environment_DEFAULT.properties com o seguinte conteúdo e uma classe injetada com esses valores:

#PROPERTIES
prop1.int=1024
prop2.bool=false

Além disso, devido ao PropertyPlaceholderConfigurer instanciado no XML, pode-se utilizar os valores do arquivo de propriedades direto no XML. Por exemplo:

Assim uma nova instância de NewBean será criado e os métodos setProp1 e setProp2 serão usados para setar os valores de acordo com o conteúdo do arquivo de configurações.

 

CÓDIGO EXEMPLO

*** Editado em 14/10/15 ***
Criei um projeto de exemplo com Spring Boot pra demonstrar as possibilidades de obtenção dos dados.

Vide https://github.com/jesjobom/config-file-example.

Nessa de fazer um projeto exemplo, vi que o Spring 3 introduziu a notação de acesso a valores do PropertyPlaceholder com valor default. Por exemplo, pra tentar acesso a variável CUSTOM_ENV deixando um valor default caso não encontrado, basta incluir ‘:’ e o valor:

${CUSTOM_ENV:default}

Mas, talvez devido a essa nova feature, obtive erro sempre que não incluí valor algum à variável.

É isso pessoal. Daqui a 1~36 meses eu volto. =]