Estive lendo mais sobre o princípio da Inversão de Controle e Injeção de Dependências como uma implementação e tenho certeza de que entendi.
Parece estar basicamente dizendo 'não declare as instanciações de seus alunos dentro da classe'. Em vez disso, as instanciações devem ser passadas e atribuídas pelo construtor; 'injetado' na classe a partir de uma fonte externa.
Se é simples assim, o que parece ser, por que precisamos de estruturas como primavera ou truque que implementam isso com anotações? Estou perdendo algo fundamental aqui? Estou realmente lutando para entender qual é o uso das estruturas de injeção de dependência.
Edit: Sobre a possível duplicata, acredito que minha pergunta é mais exclusiva, pois está perguntando sobre estruturas de DI em geral, não apenas no Spring. O Spring não é apenas uma estrutura de DI, por isso há muitas razões pelas quais alguém gostaria de usar o Spring que não está relacionado ao DI.
Respostas:
Não precisamos das estruturas. É totalmente possível implementar a injeção de dependência manualmente, mesmo para um projeto relativamente grande.
Por outro lado, o uso de uma estrutura facilita, particularmente uma baseada em anotações ou na detecção automática de dependências, pois simplifica o processo: se eu decidir que preciso de uma nova dependência em uma classe, tudo o que preciso fazer é adicionar para o construtor (ou declarar um setter) e o objeto é injetado - não preciso alterar nenhum código de instanciação.
Além disso, as estruturas geralmente contêm outras funcionalidades úteis. O Spring, por exemplo, contém uma estrutura útil para programação orientada a aspectos, incluindo demarcação de transação declarativa (que é extremamente útil) e uma variedade de implementações de adaptadores que facilitam a integração de muitas bibliotecas de terceiros.
fonte
Por que precisamos de DI (Injeção de Dependência)?
O mecanismo DI separa a produção e o consumo de objetos. As dependências de que um objeto precisa são entregues de forma transparente a partir do exterior. A vantagem do mecanismo é clara: você pode trocar as dependências a qualquer momento, por exemplo, usando um Objeto Nulo para fins de teste.
Como isso é feito?
Existem várias maneiras de atingir o objetivo:
Precisamos de estruturas de DI?
Não. Não mesmo. Você pode simplesmente passar todas as instâncias para outros objetos manualmente. Se você tem uma aplicação pequena, não há necessidade de um contêiner de mola.
Por outro lado, as estruturas oferecem uma ajuda, gerenciando objetos:
Eles ajudam a conectar relacionamentos complexos de objetos. Você não deve escrever nenhum código padrão, para gerar instâncias e passá-las para os objetos apropriados
Eles ajudam a controlar quando um objeto é criado: você pode criar instâncias durante a inicialização do aplicativo, mas em alguns casos uma criação lenta - somente quando necessário - é melhor
Eles ajudam a controlar quantas instâncias são criadas: uma por vida útil do aplicativo ou uma por solicitação (caso você esteja fazendo programação na web)
Se você projeta um tamanho apropriado - se sente a necessidade de escrever menos código padrão -, faz totalmente sentido usar uma estrutura (DI-). Existem mais prós do que contras.
fonte
Com a primavera, é principalmente uma questão de conveniência.
Se você possui uma classe
TopLevel
que é constrói uma classeMiddleLevel
que constrói uma classeLowLevel
e percebe que precisa de um novo parâmetro de construtorLowLevel
, também é necessário adicioná-lo aTopLevel
e paraMiddleLevel
simplesmente para que, quando for a hora deMiddleLevel
construir um,LowLevel
o valor esteja disponível para que possa ser passado ao seu construtor. Com a primavera, você apenas adiciona uma anotação.Além disso, com o spring, é possível definir as dependências em um arquivo de configuração externo, em vez do xml, e isso supostamente permite gerar um novo sistema com uma fiação totalmente diferente "sem alterar nenhum código". (IMHO, isso é completamente mal direcionado, porque alterar xml não é muito diferente de alterar código e, na verdade, o código geralmente tem uma verificação de erro e verificação de tipo muito melhor do que xml.)
Outra coisa é que muitas pessoas têm medo de construtores; eles não os entendem, não gostam deles, preferem não usá-los.
fonte
MiddleLevel
, mas deve recebê-lo ao construirTopLevel
como argumento para o construtor. Da mesma formaMiddleLevel
deve receber umLowLevel
em seu construtor.Alguns anos atrás, escrevi um programa para monitorar páginas da Web, portlets da Web e até mesmo determinadas tabelas de banco de dados em uma empresa na qual eu costumava trabalhar. Queria que fosse flexível o suficiente para que o usuário pudesse especificar quais monitores seriam executados e com quais parâmetros (URLs, logins, critérios de sucesso etc.). Então, eu escrevi para ler um arquivo XML e usar a reflexão Java para instanciar as classes especificadas e usar métodos setter para definir os parâmetros especificados.
Mais tarde, descobri que o Spring fará a mesma coisa por você e muito mais.
Então, no meu caso, descobri que
O uso de uma estrutura de injeção de dependência ajuda a tornar o programa flexível e facilita a especificação de como ele funcionará (dentro de parâmetros bem definidos, é claro).
O uso de uma estrutura DI de terceiros evita que você tenha que reinventar a roda.
fonte