Mas, não funcionou aqui. Não sei se fiz algo de errado. Tenho o @Component anotado.
[code]private ClienteDao clientes;
@Autowired
public void setClientes(ClienteDao clientes)
{
this.clientes = clientes;
}[/code]
Preciso fazer alguma outra configuração? Ou o @Component anotado já basta?
P.S: Não posso fazer a injeção no construtor. Porque essas classes serão serviços do BlazeDS (comunicação com um cliente em Flex) e o BlazeDS exige que a classe tenha ao menos um construtor nulo. Ou seja, a injeção por construtor não funcionaria.
Ainda não consegui montar o workspace para debugar o BlazeDS para verificar, com certeza, se é ele quem cria a classe.
Mas, eu acredito que seja ele.
Para adiantar:
-Se BlazeDS não é quem cria a classe = VRaptor deveria injetar corretamente
-Se BlazeDS é quem cria a classe = VRaptor não conseguirá injetar
Certo?
Então, pergunto: Se o VRaptor não conseguirá injetar. Tenho como fazer essa injeção do @Component “manualmente” (sem depender do VRaptor). Usando um dos providers como Spring, Guice ou Pico?
Então… o que você quer dizer em fazer um request para a aplicação VRaptor?
Mais informações:
O projeto Java estava rodando com VRaptor e estava disponibilizando os serviços por HTTP (@Resource). Então, se eu chamar no Flex os dados por HTTP irá fazer o request diretamente no VRaptor. E funcionará tanto a injeção por construção, como também acho que funcionará no setter.
No entanto, a forma mais usada e rápida de comunicação no Flex é por RemoteObject. E quem faz a comunicação entre o cliente e o servidor é o BlazeDS. Então, no servidor estou com o VRaptor, onde tem serviços sendo disponibilizados como HTTP. Mas, gostaria de disponibilizar o acesso a alguns dados por RemoteObject.
Ele tem um arquivo de configuração xml onde atribuo uma id para cada serviço disponibilizado e informo o package onde está o serviço. Depois, no Flex eu só passo a localização do servidor e o nome do serviço que será chamado. O Flex não tem nenhuma ligação com o servidor Java. Tudo passa pelo BlazeDS.
Portanto, creio, que o BlazeDS receba essa mensagem com o id do serviço que ele precisa chamar. E ela fica responsável por criar a classe. (senão não teria necessidade de informar o package…)
Não entendi ainda, por que o BlazeDS como responsável por criar a classe, a injeção das dependencias não funciona? Com nenhum framework ela funcionaria?
Essa servlet é uma fachada para todos os acessos, ou seja, TODA requisição realizada pelo cliente Flex (através do AMF) o servidor Java recebe através dessa servlet. Portanto, passa pelo VRaptor.
A requisição também passa pelo provider:
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
No entanto, nesse momento que a classe passa pelo provider é apenas uma mensagem que contém a localização do serviço, parametros, e outras informações da requisição. (Não existe a classe criada!)
Depois, por dentro do BlazeDS é criada a classe que executa a lógica e retorna o resultado em outra mensagem.
Vou verificar se essa classe responsável por criar o serviço não tem uma interface que eu possa implementar para alterar o comportamento da criação. Se eu conseguisse, teria uma maneira do VRaptor injetar daí?
Stacktrace:
[quote]15:42:35,133 DEBUG [VRaptor ] VRaptor received a new request
15:42:35,145 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
15:42:35,146 DEBUG [DefaultResourceTranslator] trying to access /messagebroker/amf
15:42:35,148 DEBUG [VRaptor ] VRaptor ended the request
15:42:35,195 DEBUG [VRaptor ] VRaptor received a new request
15:42:35,204 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
15:42:35,205 DEBUG [DefaultResourceTranslator] trying to access /messagebroker/amf
[BlazeDS]Unable to create a new instance of type ‘br.com.cauirs.tipos.Quantidade’.
flex.messaging.MessageException: Unable to create a new instance of type ‘br.com.cauirs.tipos.Quantidade’. Types cannot be instantiated without a public, no arguments constructor.
at flex.messaging.util.ClassUtil.createDefaultInstance(ClassUtil.java:161)
at flex.messaging.io.amf.AbstractAmfInput.createObjectInstance(AbstractAmfInput.java:179)
at flex.messaging.io.amf.Amf3Input.readScriptObject(Amf3Input.java:409)
at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:152)
at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
at flex.messaging.io.amf.Amf3Input.readScriptObject(Amf3Input.java:437)
at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:152)
at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
at flex.messaging.io.amf.Amf3Input.readScriptObject(Amf3Input.java:437)
at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:152)
at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
at flex.messaging.io.amf.Amf3Input.readArray(Amf3Input.java:358)
at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:156)
at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
at flex.messaging.io.amf.Amf3Input.readScriptObject(Amf3Input.java:437)
at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:152)
at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
at flex.messaging.io.amf.Amf0Input.readObjectValue(Amf0Input.java:123)
at flex.messaging.io.amf.Amf0Input.readArrayValue(Amf0Input.java:359)
at flex.messaging.io.amf.Amf0Input.readObjectValue(Amf0Input.java:127)
at flex.messaging.io.amf.Amf0Input.readObject(Amf0Input.java:94)
at flex.messaging.io.amf.AmfMessageDeserializer.readObject(AmfMessageDeserializer.java:227)
at flex.messaging.io.amf.AmfMessageDeserializer.readBody(AmfMessageDeserializer.java:206)
at flex.messaging.io.amf.AmfMessageDeserializer.readMessage(AmfMessageDeserializer.java:126)
at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:145)
at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:291)
at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:353)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at br.com.caelum.vraptor.resource.DefaultResourceNotFoundHandler.couldntFind(DefaultResourceNotFoundHandler.java:41)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:71)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:636)[/quote]
Confirmado. Tenho como modificar o modo que o BlazeDS cria o objeto.
Ao passar pelo servlet é um objeto do tipo RemotingMessage com as informações da requisição. Ai utiliza um Adapter para fazer a criação do objeto. Por padrão, é usado o JavaAdapter. Mas, posso criar qualquer um…
Então, é o BlazeDS mesmo quem cria o objeto. Porém, utilizando um Adapter personalizado a classe estará no meu projeto posso dizer o que fazer com o objeto criado.
Tenho como “ativar” essa injeção de dependências após a criação do objeto?
Acabamos disponibilizar o plugin para fazer a chamada do seu controller pelo BlazeDS.
Você pode baixar o jar (vraptor-flex.jar) na área de downloads do VRaptor no github: https://github.com/caelum/vraptor/
Na página do projeto (https://github.com/caelum/vraptor/tree/master/vraptor-plugin-flex) tem uma breve explicação sobre a configuração do plugin, mas já aproveitando a resposta, para a chamada funcionar você precisa registrar a factory do VRaptor no seu service-config.xml
Nesta versão já estamos suportando interceptors, mas como nem todo interceptor faz sentido tanto para o flex quanto para o html comum, criamos uma nova anotação @FlexIntercepts que deve anotar um classe que implementa a mesma interface Interceptor. (Uma classe que implementa Interceptor PODE usar a @Intercepts e @FlexIntercepts ao mesmo tempo sem problemas)