[RESOLVIDO] Criando Objetos pelo Spring

7 respostas
Oenning

Acho que é mais fácil explicar por código. Tenho uma classe (resumidamente) assim:

public class SuccessLoginCommand implements Command {
	
	private LoginHistoryDao loginHistoryDao;
	private Clock clock;
	private Customer customer;
	
	public SuccessLoginCommand(Customer customer) {
		this.customer = customer;
	}
	
	@Autowired
	public void setClock(Clock clock { 
		this.clock = clock;
	}
	
	@Autowired
	public void setLoginHistoryDao(LoginHistoryDao loginHistoryDao) { 
		this.loginHistoryDao = loginHistoryDao;
	}
	
	@Override
	public void execute() { 
		... 
	}
	
}

Aqui eu dependo das dessas interfaces que é resolvido pelo Spring (@Autowired) e pelo Customer que eu passo por parâmetro. A questão é, como instancio essa classe?

Assim?

Command cmd = new SuccessLoginCommand(customer); //O que eu faço aqui para que o Spring injete as dependência

Ou assim?

Me parece que a segunda forma é a mais correta, mas não sei que classe resolve isso.
Outro detalhe que pode ser relevante é que estou usando a abordagem Annotation-Driven, não estou definindo minhas beans em Xml.

Obrigado :slight_smile:

7 Respostas

L

Se o objeto customer não existir no momento da instanciação do objeto da classe SuccesLoginCommand, que é antes mesmo da sua aplicação começar, então é errado colocar o Customer como construtor. (E não, não há como obter um bean passando objetos no construtor; a instanciação e a obtenção do bean são momentos diferentes.)

Coloque o customer como argumento do método execute(). Ou então, transforme o bean em escopo de session (se estiver no contexto web) e crie um método para receber esse customer.

Oenning

Ok, entendi. Mas caso eu coloquei o Customer como argumento do execute().
Como eu obtenho o bean no meu código?

Posso estar fazendo alguma confusão, mas venho do C# e usava o StructureMap (Framework DI) e lá eu faria isso:

Command cmd = ObjectFactory.GetInstance<SuccesLoginCommand>();
cmd.execute(customer);

Isso faria o StructureMap resolver todas as dependências (DAO e Clock neste caso) e me retornar a classe concreta (SuccesLoginCommand), pronto para uso.
Como ficaria no Spring? Ou estou fazendo errado? :roll:

Valeu!

_

Eae blz?

Cara, acho que tem um problema aí, se você fizer a instanciação na mão o Spring não irá injetar as dependências.

A classe SuccessLoginCommand não possui nenhuma anotação? Tipo @Component?

[]'s

Oenning

Acho que agora caiu a ficha com esse @Component.
Acabei de ler este artigo aqui http://renidev.wordpress.com/2009/02/02/how-to-use-springs-context-component-scan-and-annotation/.

Ja já vou testar. Mas por exemplo, eu tenho o SuccessLoginCommand e FailureLoginCommand.
Dentro do meu Service, dependendo da situação, se o login deu certo eu crio o Success, senão, o Failure.

Como ficaria? Pelo visto eu vou ter que fazer o spring injetar os dois commands no meu serviço mas só vou usar um. É isso?
Porque, pelo visto, não tem como o spring injetar uma classe concreta baseada em uma situação, no meu caso, o sucesso ou falha no login.

Obrigado pela ajuda pessoal!

_

Um, injetar os dois serviços e só usar um? Soa um pouco estranho.

Na anotação @Component você pode colocar uma string que será o identificador do bean, por exemplo, @Component(“sucessLoginCommand”) para a classe SucessLoginCommand e @Component(“failureLoginCommand”) para a classe FailureLoginCommand.

No seu service você usa o método ApplicationContext.getBean(“beanId”, class) para recuperar o bean que você precisa, sucessLoginCommand ou failureLoginCommand. Não sei se é a melhor opção, mas acho que usaria assim ao invés de injetar os dois serviços.

[]'s

Oenning

Poxa, ficou ótimo, resolveu certinho. Achei que eu iria me ferrar nos testes unitários, mas consegui resolver direitinho com mocks :smiley:

Obrigado pela ajuda pessoal.

_

Legal cara.

Só adiciona [RESOLVIDO] no título do tópico!

[]'s

Criado 5 de julho de 2010
Ultima resposta 5 de jul. de 2010
Respostas 7
Participantes 3