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:
public class PagamentoService { @Inject private PagamentoDAO dao; }
Quando 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:
public class PagamentoService { private PagamentoDAO dao; @Inject public setPagamentoDao(PagamentoDAO pDao){ dao = pDao; } }
No exemplo a cima, estou solicitando ao Guice que ele injete PagamentoDAO no método set.
Exemplo de uso do @Inject em um construtor:
public class PagamentoService { private PagamentoDAO dao; @Inject public PagamentoService(PagamentoDAO pDao){ dao = pDao; } }
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:
public MyModule extends AbstractModule { ... /** * @return ICriticaRepository */ @Provides @CriticaInDbRepository public ICriticaRepository provideCriticaInDbRepository() { return new CriticaRepositoryEmBancoImpl(); } /** * @return ICriticaRepository */ @Provides @CriticaInMemRepository public ICriticaRepository provideCriticaInMemRepository() { return new CriticaRepositoryEmMemoriaImpl(); } ... }
No exemplo a cima, criamos uma modulo contendo dois method providers. Nas linhas 7 e 16, podemos notar as anotações @CriticaInDbRepository e @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:
... @Inject @CriticaInMemRepository private ICriticaRepository criticaRepository; ...
Pronto, assim o Guice saberá o que deve “entregar”, quando for solicitado.
Abaxio segue o código de uma das anotações qualificadoras:
@Qualifier @Retention(RetentionPolicy.RUNTIME) public @interface CriticaInMemRepository { // Interface que tipifica o repositorio de CriticaInMemRepository }
@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:
@Inject public RealBillingService(@Named("Checkout") CreditCardProcessor processor, TransactionLog transactionLog) { ... }
O binding configuramos assim:
bind(CreditCardProcessor.class) .annotatedWith(Names.named("Checkout")) .to(CheckoutCreditCardProcessor.class);
@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.
@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:
// 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 (){..}
Mais informações sofre definição de escopo, acesse o User Guide.
[…] a trás fiz dois posts fando sobe o Guice, Injeção de dependência com Guice #1: Introdução e Injeção de dependência com Guice #2: Anotações, o primeiro falando sobre o que é e seu objetivo, e o segundo como usar-lo em uma aplicação […]
CurtirCurtir