Bom dia,
Estou desenvolvendo um site com Spring MVC, e durante minha modelagem dos dados, algumas classes de modelo precisaram ser construídas a partir de argumentos:
Ex:
public class Exemplo
{
public Execmplo(String argumento)
{
//Ação...
}
}
Com isso, o Spring MVC apresenta erro ao tentar injetar esta dependencia nos Actions dos Controller que precisam do uso de algum objeto montado dessas classes argumentadas.
Alguém saberia me dizer se há algum modo de fazer com que o Spring monte esses objetos sem eu ter que remover os parametros do construtor ?
Obrigado !
Use sobrecarga de construtores e crie um construtor ser argumentos, mesmo vazio
public class Classe{
public Classe(){}
public Classe(int valor){
valor++;
}
}
[quote=drsmachado]Use sobrecarga de construtores e crie um construtor ser argumentos, mesmo vazio
public class Classe{
public Classe(){}
public Classe(int valor){
valor++;
}
}
[/quote]
Mas isso vai contra minha modelagem, em algumas de minhas classes não quero que seja possível a instanciação da mesma sem alguns argumentos(que serão imutaveis)…
Ex:
public class Exemplo
{
public Receita(Usuario autor,Calendar data)
{
this.autor = autor.clone();
this.data = data;
}
}
Entende ?
nesse caso, o autor e a data do modelo devem ser informados no momento da construção.
Então esqueça o Spring. Sua modelagem “espertalhona” vai contra o funcionamento do Spring.
O Spring usa reflection para instanciar classes. As configurações determinadas em XML ou annotations ou programaticamente e que definem quais beans o Spring vai injetar apenas servem para que ele possa fazer o bendito
Class.forName("br.com.pacote.app.NomeDaClasse");
E isso implica em existir, no mínimo, um construtor padrão e nenhum outro ou, então, ao menos um construtor explicitamente definido, sem argumentos.
Você escolhe, quebrar a modelagem ou desistir do Spring.
[quote=drsmachado]Então esqueça o Spring. Sua modelagem “espertalhona” vai contra o funcionamento do Spring.
O Spring usa reflection para instanciar classes. As configurações determinadas em XML ou annotations ou programaticamente e que definem quais beans o Spring vai injetar apenas servem para que ele possa fazer o bendito
Class.forName("br.com.pacote.app.NomeDaClasse");
E isso implica em existir, no mínimo, um construtor padrão e nenhum outro ou, então, ao menos um construtor explicitamente definido, sem argumentos.
Você escolhe, quebrar a modelagem ou desistir do Spring.[/quote]
Eu acredito que o Spring tenha alguma “marotagem” pra fazer isso, só não sei como…
Vou aguardar outros posts…
Encontrei algumas coisas na internet, mas ainda não resolveu meu problema:
O pessoal fala para configurar no application-context do Spring a declaração do bean com seus argumentos no construtor:
<bean class="br.com.ggdio.testes.Teste">
<constructor-arg index="0" name="valorArg" type="java.lang.String"/>
</bean>
Nesse caso declara-se a posição do valor no construtor, seu tipo e seu nome.
Mas ainda não resolver meu problema…
[quote=drsmachado]Nada como a pesquisa.
http://forum.springsource.org/showthread.php?18640-Injecting-runtime-constructor-arg-properties
Talvez ajude.
Eu só lembrava da opção no argument.[/quote]
Então, eu encontrei esses tutoriais durante minha pesquisa também…
Mas esse modo só serve para instanciar uma classe durante a inicialização do sistema, passando alguns valores de argumento.
Agora, para fazer com que o Spring instancie uma classe com argumentos a partir de uma chamada do usuário num Controller, ai ja não sei.
Queria que ele fizesse a injeção de um objeto assim:
public class Exemplo
{
public Exemplo(String argumento)
{
//Ação...
}
}
@Controller
public classe ExemploController
{
@RequestMapping("caminho")
public void testeInjecao(Exemplo exemplo)
{
//Ações...
}
}
Ai, este Action do Controller seria chamado a partir de um formulario do front-end, e com os dados do Front-End, o objeto deveria ser criado pelo Spring…Assim com é feito normalmente com uma classe com contrutor default…
O que quer dizer com isto?
O Spring irá instanciar e deixar em memória um objeto de cada bean definido nas configurações da aplicação.
Quando este objeto for invocado em algum método que está sendo executado, o Spring simplesmente pega o mesmo da memória e o injeta.
Ele não instancia on-demand.
Então, o que eu preciso é que ele me passe um objeto instanciado num RequestMapping, entendeu ?
Por exemplo, no cadastro de uma Pessoa que tem nome, sobrenome e idade…o nome, por exemplo, deve ser passado no construtor.
Então, no front end, quando o usuario clicar em confirmar, os dados de Pessoa que ele digitou no form, devem ser passados para o Front Controller do Spring, no qual deve montar o objeto usando os setters para sobrenome e idade o construtor para o nome…
E disso que preciso, que ele monte um bean que tenha construtor argumentado.
Ninguém tem idéia de como reoslver isto ?
Por hora vou criar um construtor default e um set para os valores imutaveis, mas isto vai contra minha modelagem, realmente preciso fazer com que o Spring injete os dados seguindo minha regra…
Se algúem souber de algo por favor poste aqui, obrigado…