Olá pessoal,
vou tentar explicar a minha situação. Hoje utilizamos o vraptor na nossa “camada de serviços” http.
São serviços simples, que fazem a integração com diversos serviços legados da empresa.
Em um novo projeto, que usará vraptor também para a parte web, surgiram algumas idéias na equipe para facilitar o desenvolvimento.
Uma delas é extrair uma interface dos controladores e, no caso do cliente ser também java, utilizar essa interface para construir um proxy que faça a chamada real, via http.
Começamos a experimentar essa idéia, pois em tese o cliente ficaria + “simples”, como por exemplo:
//acessa o resource cliente e o salva:
clients.save( newClient )
Tivemos alguns problemas:
Com isso, o vraptor não conseguue extrair informações dos métodos. Alteramos as annotations para que possam ser herdadas.
Os testes passaram, mas existe algum motivo para que elas não sejam passíveis de serem herdadas?
- O vraptor registra a interface como controlador.
O vraptor encontra a interface. No nosso caso, estamos utilizamos spring. Quando o vraptor tenta obter o controlador para processar a request,
o spring não consegue instanciar a interface e lança uma exceção.
Ao fazer scanner o vraptor usa uma AnnotationDB, que já retorna a interface com as annotations.
Pra resolver, registro a implementação do controller no spring com um @Component e alterei a a implementação do SpringBasedContainer de:
Map<String, T> beans = parentContext.getBeansOfType(type);
for (Entry<String, T> def : beans.entrySet()) {
BeanDefinition definition = parentContext.getBeanFactory().getBeanDefinition(def.getKey());
if (isPrimary(definition) || hasGreaterRoleThanInfrastructure(definition)) {
return def.getValue();
}
para:
String[] beanNamesForType = parentContext.getBeanNamesForType(type);
for( String beanName : beanNamesForType ){
BeanDefinition definition = parentContext.getBeanFactory().getBeanDefinition(beanName);
if (notAnInterface(beanName) && isPrimary(definition) || hasGreaterRoleThanInfrastructure(definition)) {
return (T) parentContext.getBean(beanName);
}
}
Desta forma, quando o vraptor depara com uma interface, procura por uma implementação que a satisfaça.
Seria essa a melhor forma de atingir esse objetivo?
- Vraptor não consegue obter nomes de parâmetros.
Tivemos que utilizar a @Named nos parâmetros da interface.
Claramente, esta abordagem de utilização tem também pontos fracos, como:
[list]Acomplamento do projeto cliente com as interfaces;[/list]
[list]Código “mágico” realizando as requisições - apesar de bem testado e com boas mensagens de erro, pode ser ruim debugar ou procurar erros;[/list]
[list]Se utilizarmos objetos como parâmetros dos controladores (o que acho muito bacana no vraptor), o cliente também deverá conhecê-los[/list]
O que vocês acham dessa abordagem? A simplicidade de uso compensa as situações citadas acima?
Mais uma vez, parábens pelo excelente projeto e obrigado pela ajuda.
