Plugin para trabalhar com CDI no VRator

99 views
Skip to first unread message

Otávio Garcia

unread,
Sep 29, 2011, 6:24:09 PM9/29/11
to caelum-vr...@googlegroups.com
Pessoal, tenho um projeto que usa EJB + CDI Beans. Essa semana extraí esses componentes e criei um projeto para poder trabalhar com CDI Beans no VRaptor. O projeto está aqui: https://github.com/garcia-jj/vraptor-plugin-cdi. A documentação é muito fraca e não escrevi ainda os testes, pois ele ainda é apenas uma idéia inicial.

Para usar em meu projeto bastaria então injetar o ServiceLocator nas classes e chamar ServiceLocator.get(MeuBean.class, AlgumQualifier.class). Só que chamar assim é chato, prefiro injetar diretamente meus CDI Beans.

Como uso EJB com interface local/remota, criei uma factory para cada interface. Sendo assim eu crio algo do tipo:

public class RateServiceFactory implements ComponentFactory<RateServiceLocal> {

    private final ServiceLocator serviceLocator;

    public RateServiceFactory(ServiceLocator serviceLocator) {
        this.serviceLocator = serviceLocator;
    }

    public RateServiceLocal getInstance() {
        return serviceLocator.get(RateServiceLocal.class);
    }
}

Agora caí no problema de ter que criar uma factory para cada EJB. O que antes era chato ficou mais ainda. Pelo menos agora eu consigo injetar meus beans de forma mais inteligente, e para contornar isso criei um builder do Eclipse + Javassist que gera estas classes em tempo de build, algo parecido com o hibernate-modelgen. Mesmo assim não fiquei satisfeito, porque mesmo sendo automatizadas, essas classes tinham que ser geradas.

Então pergunto: há uma forma mais pratica sem ter que criar uma ComponentFactory para cada CDI Bean? Tentei fazer uns testes sobrescrevendo o Container conforme código abaixo, mas acabei ganhando um StackOverflowError, por motivos obvios. O delegate recebido no construtor acaba sendo a própria instância, entrando em loop infinito.

public class CustomContainer implements Container {
    private Container delegate;

    [...]
}

Pensei em último caso sobrescrever direto a implementação do Guice (preferia deixar cross-provider). Dessa forma recebo o erro abaixo:

1) No implementation for icob.model.service.RateServiceLocal was bound.
  while locating icob.model.service.RateServiceLocal
    for parameter 5 at icob.web.controller.CustomerController.<init>(CustomerController.java:45)
  at br.com.caelum.vraptor.ioc.guice.GuiceComponentRegistry.bindToConstructor(GuiceComponentRegistry.java:129)

O que vocês me sugerem?

Lucas Cavalcanti

unread,
Sep 29, 2011, 6:37:28 PM9/29/11
to caelum-vr...@googlegroups.com
especificamente no Guice dá pra tentar registrar um Provider de uma Interface específica, e mandar ele injetar a classe que foi pedida...

no spring não sei se tem algo do tipo, mas se vc receber um Container no construtor de uma classe que tb estende Container, ele vai injetar
a outra classe. no pico acho que também



2011/9/29 Otávio Garcia <ota...@otavio.com.br>

--
You received this message because you are subscribed to the Google Groups "caelum-vraptor-dev" group.
To post to this group, send email to caelum-vr...@googlegroups.com.
To unsubscribe from this group, send email to caelum-vraptor-...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/caelum-vraptor-dev?hl=en.

Otávio Garcia

unread,
Sep 29, 2011, 11:32:25 PM9/29/11
to caelum-vr...@googlegroups.com
Lucas, a minha intenção nesse plugin é deixar independente de provider, por isso quero achar uma opção transparente nesse sentido. A idéia é que você possa injetar qualquer CDI Bean como se fosse um componente do VRaptor.

Abraços

2011/9/29 Lucas Cavalcanti <lucasm...@gmail.com>

Lucas Cavalcanti

unread,
Sep 29, 2011, 11:48:11 PM9/29/11
to caelum-vr...@googlegroups.com
a gente pode padronizar um componente que faz isso, e implementar esse componente nos 3 providers

2011/9/30 Otávio Garcia <ota...@otavio.com.br>
Reply all
Reply to author
Forward
0 new messages