Skip to content

Spring Boot: utilizar @Autowired é uma boa prática?

Se você trabalha com Spring Boot há algum tempo, sabe o quanto a injeção de dependências do framework facilita no desenvolvimento e permite que você tenha um maior desacoplamento entre componentes do seu software.

Mas antes que eu responda a pergunta do título desse artigo, do que se trata a injeção de dependências, ou Dependency Injection (DI), e de que forma podemos injetar as dependências no Spring Boot?

Spring Boot e Dependency Injection

Uma aplicação é composta por diversos objetos que interagem uns com os outros para cumprir objetivos determinados. Dessa forma a injeção de dependências num sentido mais simples pode ser compreendida como a injeção de objetos para um objeto ou framework em tempo de execução. Essa injeção pode ocorrer de três formas no Spring: field injection, setter injection ou constructor injection.

Field injection é quando anotamos o field com @Autowired, como no exemplo abaixo:

@Component
public class MyComponent {

  @Autowired
  private MyService myService;

  // Business logic goes here

}

Setter injection é quando anotamos o setter do field com @Autowired, como no exemplo abaixo:

@Component
public class MyComponent {

  private MyService myService;

  @Autowired
  public void setMyService(MyService service) {
    this.myService = service;
  }

  // Business logic goes here

}

Constructor injection é quando declaramos o field com o modificador final e injetamos no construtor da classe, como no exemplo abaixo:

@Component
public class MyComponent {

  private final MyService myService;

  public MyComponent(final MyService service) {
    this.myService = service;
  }

  // Business logic goes here

}

Não devo usar @Autowired?

Não recomendo, mas aconselho que caso o faça, faça entendendo as consequências. Imagine que você inicia o desenvolvimento de um sistema e meses depois percebe que aquela classe de service cresceu muito e carrega consigo dezenas de dependências. Sempre que você precisou injetar uma nova dependência, bastou declarar o field e anotar com @Autowired, certo? É a maneira mais utilizada, é tão simples e rápido que você por vezes não para e reflete sobre o que está fazendo. Talvez se refletisse, perceberia que era o momento de refatorar partes do sistema para melhorar sua manutenção.

Nesse artigo quero te dar uma dica: utilize o constructor injection ao invés das opções com @Autowired pois os benefícios são muito maneiros: esse método evidencia o crescimento de sua classe, já que te obriga a refatorar o construtor a cada nova dependência, e também facilita sua vida na hora de escrever testes unitários.

O constructor injection é positivo para a escrita de testes unitários pois permite que você crie o mock das dependências de forma mais simples e com maior controle ao invés de depender de anotações do Mockito como o @InjectMocks. Pense por exemplo em um caso de teste em que você precise mockar parte das dependências mas uma em específico você precisa que seja a implementação real: injetando as dependências no construtor do componente em seu teste unitário você alcança isso com facilidade.

Leitura recomendada

Caso queira entender um pouco mais sobre o conceito de Dependency Injection, recomendo este ótimo artigo do Martin Fowler, intitulado “Inversion of Control Containers and the Dependency Injection pattern.


Por hoje é isso. Caso tenha alguma crítica ou sugestão, utilize a caixa de comentários abaixo, seu feedback é muito bem vindo. Ah, caso não tenha entendido por que usei um Megazord como imagem deste artigo, pense em acoplamento. Até a próxima!

Published inProgramação

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *