Injeção de dependência com Guice #2: Anotações

Tempo de leitura: menos de 1 minuto

guice

Fala galera!

Dando continuidade ao post Injeção de dependência com Guice #1: Introdução, hoje vou falar sobre as anotações da JSR e do Guice e como usa-las.

Anotações

@Inject

A @Inject com certeza é a anotação mais usada quando falamos de injeção de dependência com Guice. Ela é usada para informar ao Guice quando a classe depende da instância do um objeto qualquer e quer que o Guice se encarregue de “entregar” esta instância.

Existem 3 formas de declarar a pendência de uma classe usando o @Inject:

  • Atributo;
  • Método;
  • Construtor.
Exemplo de uso do @Inject em um atributo:

[code language=”java”]
public class PagamentoService {
@Inject
private PagamentoDAO dao;
}
[/code]

googleQuando a classe PagamentoService for injetada através do injetor, automaticamente o Guice injetará uma instancia de PagamentoDAO, previamente configurado no modulo/binding.

Exemplo de uso do @Inject em um método:

[code language=”java”]
public class PagamentoService {
private PagamentoDAO dao;

@Inject 
public setPagamentoDao(PagamentoDAO pDao){
dao = pDao;
}
}
[/code]

No exemplo a cima, estou solicitando ao Guice que ele injete PagamentoDAO no método set.

Exemplo de uso do @Inject em um construtor:

[code language=”java”]
public class PagamentoService {
private PagamentoDAO dao;

@Inject
public PagamentoService(PagamentoDAO pDao){
dao = pDao;
}
}
[/code]

No exemplo a cima, estou solicitando ao Guice que ele injete PagamentoDAO no construtor do  PagamentoService.

Estas são as formas de usar o @Inject.

@Qualifier

Na maioria das vezes, criamos o binding ligando uma interface ao uma única implementação, normalmente usando a anotação @ImplementedBy. Em alguns casos existe várias implementações para uma determinada interface. Neste caso necessitamos identificar qual implementações queremos o Guice “entregue”, para isso usamos os qualifiers.

@Qualifier nada mais é que uma tag, rótulo, que indica ao Guice qual instância de implementação desejamos receber. No binding, “tagiamos” casa implementação com uma anotação do tipo @Qualifier, como pode ser visto abaixo:

[code language=”java” highlight=”7,16″]
public MyModule extends AbstractModule {

/**
* @return ICriticaRepository
*/
@Provides
@CriticaInDbRepository
public ICriticaRepository provideCriticaInDbRepository() {
return new CriticaRepositoryEmBancoImpl();
}

/**
* @return ICriticaRepository
*/
@Provides
@CriticaInMemRepository
public ICriticaRepository provideCriticaInMemRepository() {
return new CriticaRepositoryEmMemoriaImpl();
}

}
[/code]

No exemplo a cima, criamos uma modulo contendo dois method providers. Nas linhas 7 e 16, podemos notar as anotações @CriticaInDbRepository@CriticaInMemRepository respectivamente. Estas anotações são qualifiers, ou seja, elas estão rotulando os providers, a fim de informar o Guice o que “entregar” quando for solicitado a instância de ICriticaRepository.

Mas isso não é tudo, na classe onde declaramos a dependência, através da anotação @Inject, precisamos também informar qual das implementações precisamos, desta forma:

[code language=”java” highlight=”3″]

@Inject
@CriticaInMemRepository
private ICriticaRepository criticaRepository;

[/code]

Pronto, assim o Guice saberá o que deve “entregar”, quando for solicitado.

Abaxio segue o código de uma das anotações qualificadoras:

[code language=”java”]
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface CriticaInMemRepository {
// Interface que tipifica o repositorio de CriticaInMemRepository
}
[/code]

@Named

A anotação @Named é muito parecida com a @Qualifier, inclusive serve para a mesma coisa, rotular as implementações.

No entanto não existe a necessidade de criar uma nova anotação, basta usa-la informando um identificador, desta forma:

[code language=”java” highlight=”2″]
@Inject
public RealBillingService(@Named("Checkout") CreditCardProcessor processor,
TransactionLog transactionLog) {

}
[/code]

O binding configuramos assim:

[code language=”java” highlight=”2″]
bind(CreditCardProcessor.class)
.annotatedWith(Names.named("Checkout"))
.to(CheckoutCreditCardProcessor.class);
[/code]

@Provides

Quando o Guice não sabe como criar uma instância de sua implementação, seja pela quantidade de implementações de uma interface, ou pela complexabilidade de instância-la, nestes caso utilizamos a anotação @Provides.

Um exemplo do uso desta anotação no binding usando o qualifier. Podemos usar ela também na substituição de Factory por exemplo.

Veja mais em bindings

@Singleton

Por padrão, o Guice sempre retorna uma nova instância a cada solicitação de um mesmo tipo de objeto. No entanto, essa configuração pode ser alterada, possibilitando a definição de escopes.

A anotação @Singleton, serve para definir o escopo de aplicação ao configurar um binding, assim, o Guice “entregará” sempre a mesma instância quando for solicitada.

Vejamos exemplos de configuração:

[code language=”java” highlight=”2″]
// forma 1: No modulo, configurando o binding
bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
// forma 2: No modulo, na criação de method provider
@Provides @Singleton
ClasseImpl getClasse(){return new ClasseA();}

//forma 3: Na definição da classe concreta, através da anotação
@Singleton
public class ClasseImpl (){..}
[/code]

Mais informações sofre definição de escopo, acesse o User Guide.

Fontes

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *