Spring - injeção de dependência

Cada aplicativo baseado em Java possui alguns objetos que funcionam juntos para apresentar o que o usuário final vê como um aplicativo funcional. Ao escrever um aplicativo Java complexo, as classes do aplicativo devem ser o mais independentes possível de outras classes Java para aumentar a possibilidade de reutilizar essas classes e testá-las independentemente de outras classes durante o teste de unidade. A injeção de dependência (ou às vezes chamada de fiação) ajuda a unir essas classes e, ao mesmo tempo, mantê-las independentes.

Considere que você tem um aplicativo que possui um componente de editor de texto e deseja fornecer uma verificação ortográfica. Seu código padrão seria mais ou menos assim -

public class TextEditor {
   private SpellChecker spellChecker;
   
   public TextEditor() {
      spellChecker = new SpellChecker();
   }
}

O que fizemos aqui é criar uma dependência entre o TextEditor e o SpellChecker. Em um cenário de inversão de controle, em vez disso, faríamos algo assim -

public class TextEditor {
   private SpellChecker spellChecker;
   
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

Aqui, o TextEditor não deve se preocupar com a implementação do SpellChecker. O SpellChecker será implementado de forma independente e fornecido ao TextEditor no momento da instanciação do TextEditor. Todo este procedimento é controlado pelo Spring Framework.

Aqui, removemos o controle total do TextEditor e o mantemos em outro lugar (ou seja, arquivo de configuração XML) e a dependência (ou seja, classe SpellChecker) está sendo injetada na classe TextEditor por meio de um Class Constructor. Assim, o fluxo de controle foi "invertido" pela injeção de dependência (DI) porque você delegou dependências efetivamente a algum sistema externo.

O segundo método de injetar dependência é por meio Setter Methodsda classe TextEditor onde criaremos uma instância de SpellChecker. Esta instância será usada para chamar métodos setter para inicializar as propriedades do TextEditor.

Assim, DI existe em duas variantes principais e os dois subcapítulos seguintes cobrirão ambos com exemplos -

Sr. Não. Tipo e descrição de injeção de dependência
1 Injeção de dependência baseada em construtor

A DI baseada em construtor é realizada quando o contêiner invoca um construtor de classe com vários argumentos, cada um representando uma dependência da outra classe.

2 Injeção de dependência baseada em setter

A DI baseada em setter é realizada pelo contêiner que chama métodos setter em seus beans após invocar um construtor sem argumento ou método de fábrica estático sem argumento para instanciar seu bean.

Você pode misturar ambos, DI baseado em construtor e baseado em Setter, mas é uma boa regra usar argumentos de construtor para dependências obrigatórias e setters para dependências opcionais.

O código é mais limpo com o princípio DI e o desacoplamento é mais eficaz quando os objetos são fornecidos com suas dependências. O objeto não consulta suas dependências e não conhece a localização ou classe das dependências, em vez disso, tudo é cuidado pelo Spring Framework.