java - pattern - spring dependency injection




O que exatamente é Field Injection e como evitá-lo? (2)

Esta é uma das intermináveis ​​discussões no desenvolvimento de software, mas grandes influenciadores do setor estão ficando mais opinativos sobre o assunto e começaram a sugerir a injeção de construtor como a melhor opção.

Injeção de construtor

Prós:

  • Melhor testabilidade . Você não precisa de nenhuma biblioteca de zombaria ou um contexto Spring em testes de unidade. Você pode criar um objeto que deseja testar com a nova palavra-chave. Esses testes são sempre mais rápidos porque não dependem do mecanismo de reflexão. ( Esta pergunta foi feita 30 minutos depois. Se o autor tivesse usado injeção de construtor, não teria aparecido).
  • Imutabilidade . Depois que as dependências são definidas, elas não podem ser alteradas.
  • Código seguro . Após a execução de um construtor, seu objeto está pronto para ser usado, já que você pode validar qualquer coisa que tenha sido passada como um parâmetro. O objeto pode estar pronto ou não, não há estado intermediário. Com injeção de campo, você introduz uma etapa intermediária quando o objeto é frágil.
  • Expressão mais limpa de dependências obrigatórias . A injeção de campo é ambígua nesse assunto.
  • Faz os desenvolvedores pensarem no design . dit escreveu sobre um construtor com 8 parâmetros, que na verdade é o sinal de um projeto defeituoso e o anti-padrão do objeto Deus . Não importa se uma classe tem 8 dependências em seu construtor ou em campos, é sempre errado. As pessoas estão mais relutantes em adicionar mais dependências a um construtor do que através de campos. Ele funciona como um sinal para o seu cérebro de que você deve parar por um tempo e pensar sobre sua estrutura de código.

Contras:

  • Mais código (mas os IDEs modernos aliviam a dor).

Basicamente, a injeção de campo é o oposto.

Eu li em alguns posts sobre Spring MVC e Portlets que a injeção de campo não é recomendada. Porque eu estou tentando pegar um Então eu me perguntei se eu estou usando injeção de campo e não posso responder. Pelo que entendi, injeção de campo é se você injetar um Bean em um atributo com @Autowired assim:

CartController.java:

...
@Autowired
private Cart cart;
...

BookshopConfiguartion.java:

@Configuration
public class BookShopConfiguration {

@Bean
public Cart cart(){
    return new Cart();
}
//more configuration

Meu Cart.java é usado para armazenar e fornecer informações sobre os livros no carrinho.

Durante minha pesquisa li sobre injeção de construtor :

MyComponent.java:

...
public class MyComponent{
private Cart cart;

@Autowired
public MyComponent(Cart cart){
   this.cart = cart;
}
...

Quais são as vantagens e desvantagens de ambos os tipos de injeções?

EDIT 1: Como esta questão é marcada como duplicado desta questão eu verifiquei. Porque não há nenhum exemplo de código nem na pergunta nem nas respostas não está claro para mim se estou correto com o meu palpite qual tipo de injeção eu estou usando.


Questão de gosto. É sua decisão.

Mas eu posso explicar, porque eu nunca uso injeção de construtor .

  1. Eu não quero implementar um construtor para todos os meus @Service , @Repository e @Controller . Quer dizer, existem cerca de 40-50 ou mais. Toda vez que eu adicionar um novo campo eu teria que estender o construtor. Não. Eu não quero e não preciso.

  2. E se o seu Bean (Serviço ou Controlador) exigir muitos outros grãos a serem injetados? Um construtor com 8 parâmetros é muito feio.

  3. Se estou usando o CDI, o construtor não me diz respeito.

EDIT : Vojtech Ruzicka disse:

classe tem muitas dependências e provavelmente está violando o princípio da responsabilidade única e deve ser refatorada

Sim. Teoria e realidade. Aqui está um exemplo: DashboardController mapeado para o caminho único *:8080/dashboard .

Meu DashboardController coleta muitas informações de outros serviços para exibi-las em uma página de visão geral do painel / sistema. Eu preciso desse único controlador. Então eu tenho que proteger apenas este caminho (autenticação básica ou filtro de função de usuário).





autowired