Trabalhando com diferentes ambientes
Environment é uma funcionalidade do VRaptor que nos permite definir componentes e configurações diferentes conforme o ambiente que você está: produção, testes, desenvolvimento, etc.
Você pode, por exemplo, desativar o envio de e-mails no ambiente de desenvolvimento, porém habilitar quando estiver em produção.
Configuração
Há várias formas de configurar o environment. A primeira opção é adicionando as linhas abaixo no seu web.xml
para, por exemplo, configurar o nome do environment para PRODUCTION:
<context-param>
<param-name>br.com.caelum.vraptor.environment</param-name>
<param-value>PRODUCTION</param-value>
</context-param>
A segunda opção é configurar uma propriedade na JVM. Para isso, basta iniciar a instância do seu Servlet Container ou Application Server com o seguinte parâmetro:
-Dbr.com.caelum.vraptor.environment=PRODUCTION
A terceira opção permite configurarmos o nome do environment usando as variáveis de ambiente do sistema operacional, bastando adicionar a variável VRAPTOR_ENV
.
Exemplo no windows:
set VRAPTOR_ENV=PRODUCTION
Exemplo no unix:
export VRAPTOR_ENV=PRODUCTION
Nota: A configuração usando variáveis do sistema operacional possui maior prioridade sobre a configuração de propriedades da JVM, que possui maior prioridade sobre a configuração no web.xml
.
Definindo as propriedades de um ambiente
Basta criar um arquivo de propriedades no classpath da aplicação com o nome do seu ambiente. Por exemplo, para definir as propriedades de produção, devemos criar um arquivo production.properties
:
ambiente_de_teste=false
email=production.mail@mail.com
Se você tem propriedades que são comuns a outros ambientes, você pode criar um arquivo chamado environment.properties
com as propriedades comuns. Quando você precisar usar alguma propriedade, o Environment
irá procurar primeiro no arquivo do ambiente, e caso não encontrar, irá procurar o environment.properties
.
Você também pode sobrescrever propriedades usando System Properties. Propriedades definidas nas System Properties irão sobreescrever quaisquer outras definições. Nota: Você só pode usar System Properties para sobreescrever propriedades existentes nos arquivos de propriedades e não para definir novas propriedades.
Considerando que você tenha um environment.properties abaixo: ~~~ #!properties my.prop hello ~~~
Você pode sobrescrever a propriedade existente my.prop com uma System Property: ~~~ #!java System.setProperty(“my.prop”, “bye”); environment.get(“my.prop”); //bye ~~~
Se a chave não existir no arquivo de propriedades, o método get irá lançar uma NoSuchElementException.
Acessando propriedades de ambiente no seu código
Há dois métodos para acessar as propriedades de ambiente via código: get
e getOrDefault
. O método get
retorna o valor da propriedade ou uma MissingResourceException
se a propriedade não for encontrada. Já o método getOrDefault
retorna o valor da propriedade, ou um valor padrão caso não encontrada.
@Controller
public class MeuController {
private final Environment environment;
private final MailSender sender;
/**
* @deprecated CDI eyes only
*/
protected MeuController(){
this(null, null);
}
@Inject
public MeuController(Environment environment, MailSender sender) {
this.environment = environment;
this.sender = sender;
}
public void sendMail(String email) {
if(environment.isDevelopment()) {
sender.sendMailTo(environment.get("email"));
return;
}
sender.sendMailTo(email);
}
}
No código acima, environment.get("email")
irá retornar o valor da propriedade email
. Porém caso a propriedade não existir em todos os ambientes, você pode usar o método getOrDefault
para retornar um valor padrão.
public void sendMail(String email) {
if(environment.isDevelopment()) {
sender.sendMailTo(environment.getOrDefault("email"), "noreply@vraptor.org");
} else {
sender.sendMailTo(email);
}
}
Acessando propriedades de ambiente no JSP
<c:if test="${environment.isTest()}">
<p>Você está no ambiente de teste. Suas ações aqui não afetarão o sistema.</p>
</c:if>
Enviando e-mail para: ${environment.get('email')}
Acessando arquivos de configuração de acordo com o environment
Se você precisa acessar um arquivo de configuração diferente para suas bibliotecas, de acordo com seu ambiente, você também pode utilizar o Environemnt. Basta colocar, por exemplo, seu hibernate.cfg.xml
em diretórios com o nome de seus ambientes: development e production (por exemplo). Environment.getResource(...)
retornará o resource de acordo com seu ambiente atual:
cfg = new AnnotationConfiguration();
cfg.configure(environment.getResource("/hibernate.cfg.xml"));
Para manter compatibilidade com quem não utilizava o environment, caso o arquivo não seja encontrado no diretório com o nome do ambiente, ele será carregado no diretório root (do classpath).
Injetando o valor de suas configuração programaticamente
Você também consegue injetar suas configurações programaticamente usando o @Property
, por exemplo:
@Controller
public class MeuController {
@Inject
@Property("email")
private String email;
public void sendMail(String email) {
sender.sendMailTo(email);
}
}
Neste caso, se o seu environment estiver com valor DEVELOPMENT
, vai injetar o valor que corresponde a chave email do arquivo development.properties
, se estiver com PRODUCTION
do production.properties
e assim por diante. Dessa forma você não precisa dos ifs como: if(environment.isDevelopment()) {...}
em seu código.
Outra facilidade, é que se o nome da chave for o mesmo nome do field injetado, como em nosso caso com a chave email, você pode deixar apenas o @Property
que o nome será inferido. Seu controller ficaria assim:
@Controller
public class MeuController {
@Inject
@Property
private String email;
public void sendMail(String email) {
sender.sendMailTo(email);
}
}
Você também pode definir um valor padrão para essa propriedade:
@Inject
@Property(defaultValue = "config.properties")
private String fileName;