Mas pra cada implementação preciso ter uma variavel diferente ?
Assim não fere o baixo acoplamento ?
Antes de usar o Spring eu tinha uma unica variavel do tipo IDAO que era recebida no construtor de acordo com o que era mandado da classe que faria o invoker desse business a variavel seria da implementação que eu precisava.
Mas ai depende. Sua classe business vai usar um ou mais DAOs para realizar a lógica de negócio. Pois quando a mesma for chamada e ela for realizar vários acessos ao banco, todos os DAOs envolvidos precisam estar disponíveis.
Então, não é que vai usar varios Daos na verdade dependendo da regra de negocio seria um dao x ou y, mas ambos implementam a mesma interface. Preciso ter um objeto pra cada implementação ou consigo usar uma unica, para o proprio spring de alguma forma saber qual implementação ele ira injetar ?
O Spring vai buscar a classe que implementa esta interface no caso você tem que ter apenas uma classe que implementa esta interface para não ter problemas com o Spring
hahaha acho q entendi a dúvida dele, porém não sei responder.
Acontece, que antes ele recebia as dependências pelo construtor, porém imagino q ele passava-as na mão.
Então ele tinha uma dependência da Interface X, e qdo chamasse a classe podia passar qqer implementação conforme a necessidade.
Porém usando o Spring ele acaba tendo que fixar a implementação específica através do Qualifier …
É possível fazer isso com spring, mas pra escolher a melhor forma, seria necessário mais informaçoes sobre seu caso específico.
De forma geral, eu geralmente prefiro colocar a anotaçao Autowired direto no construtor ao invés de colocar no atributo. Voce continua usando spring normalmente, mas a classe continua declarando suas dependencias explicitamente para o mundo.
Colocaria um exemplo aqui mas notei que nao sei mais colocar código no fórum novo
Voce diz que quer usar diferentes implementaçoes dependendo da sua lógica de negócios, algumas sugestoes:
Se for apenas implementacao para testes, na hora de definir o contexto do spring, voce pode apontar uma implmentaçao para produçao e outra para testes para sua interface IDAO
Se for realmente dinamico, voce pode controlar a criacao da sua TesteBusiness no seu próprio código, sem fazer o spring controlar o ciclo de vida do seu componente.
De qualquer forma, forneça mais detalhes do que precisa exatamente.
Na verdade não tenho um caso especifico ainda, estou começando a estudar o Spring e me peguei com essa duvida pois antes de conhecer o Spring eu fazia a injeção de dependência via construtor recebendo um objeto do tipo generio e quem fosse usar a classe mandaria no new da classe a implementação que precisaria. Todos exemplos que tinha visto até agora a anotação de injeção @Autowired ou @Inject estava direto na definicão da variavel, mas voce disse agora que da pra ser no construtor, acredito que > isso resolve o problema.
Se eu colocar por exemplo a anotação no contrutor :
public class Teste{
private IDAO idao;
@AutoWired
public Teste(IDAO idao){
this.idao = idao;
}
}
Assim a classe que iria fazer o invoker dessa classe teste faria assim:
public static void main(String[] args){
Teste teste = new Teste(new PessoaDao());
}
Assim o spring gerenciaria esse Bean, mesmo eu dando new ?
Nao, o spring nao gerenciaria. Quem ficaria responsável por isso seria a classe que chama a Teste.
Os beans gerenciados pelo spring, por default sao singleton (apenas uma instancia), entao nao é o comportamento mais comum que a dependencia mude a cada chamada.
Geralmente se a implementaçao mudaria a cada chamada, você poderia passar esse dao direto no método, ao invés do construtor. Ou criar várias instancias únicas do seu bean Teste, uma para cada tipo de dependencia. Depende muito do caso real.
Mas a resposta simples é que nesse caso o spring pode mais te atrapallhar do que te ajudar.
Mas fazendo assim eu entendo que eu estou ferindo o principio do baixo acoplamento, pois o fato de a variavel ser do tipo da interface e o Spring que injetar a implementação que vai ser usada não muda o fato de que a classe vai ser dependente de uma implementação x da minha interface, pois o Spring vai sempre injetar a mesma implementação.
Sim, a primeira vista pode parecer que sim. Mas você ainda tem possibilidade de passar diferentes implementaçoes, só muda o “onde” você decide isso.
No meu caso, costumo usar o construtor dos beans gerenciados pelo spring mais como uma configuraçao e os elementos mais dinamicos, passo diretamente na chamada de métodos.
Há formas mais dinamicas de se fazer isso dentro do prório spring (factory methods, por exemplo), mas como eu disse no começo, tudo depende da sua real necessidade.
Como a minha criatividade está baixa, vamos fazer o contrário: me dá um caso de uso real que esteja pensando, onde faça sentido usar diferentes implementaçoes… daí eu tento converter para usar no spring.
Um caso que eu imagino que possa ser necessário é por exemplo, eu tenho uma interface Idao e 2 daos diferentes que implementam essa interface, SGBDDao e FileDAO. Agora imagine que um único business poderia ser usado esses 2 Daos, dependendo da regra de negócio. Sem o Spring eu receberia no construtor da business uma.instancia de Idao e quem fosse instanciar a business passaria qual das 2 implementaçoes seria usada e com o polimorfismo a mesma variável de instância idao seriviria pra qualquer implementação dela. Como eu conseguiria fazer isso com o Spring?