16‐Constructor Injection - JulianeMaran32/Java-with-Spring-Boot GitHub Wiki

34. Injeção via Construtor – Parte 1

Acesse o site: https://start.spring.io/

Configurações do projeto:

  • Tipo de Projeto: Maven
  • Linguagem: Java
  • Versão do Spring Boot: 3.4.4 (no curso foi usada a 3.3.0)
  • Metadados:
    • Group: com.juhmaran (no curso: com.luv2code)
    • Artifact: springcoredemo
    • Name: springcoredemo
    • Description: Demo project for Spring Boot
    • Package name: com.juhmaran.springcoredemo
    • Packaging: Jar
    • Java: 21 (no curso: 17)
  • Dependências:
    • Spring Boot DevTools
    • Spring Web

Após configurar, clique no botão "Generate" para baixar o projeto (um arquivo .zip).

Organização local do projeto:

  1. Extraia o conteúdo do .zip.
  2. Mova a pasta do projeto para o diretório onde você está organizando o código do curso.
  3. Renomeie a pasta para 01-injecao-construtor.
  4. Importe o projeto no IntelliJ (basta arrastar a pasta e soltá-la no IntelliJ).
  5. Aguarde o download e sincronização das dependências do Maven.

35. Injeção via Construtor – Parte 2

Passo 1: Criar interface de dependência

Crie uma interface chamada Coach:

package com.juhmaran.springcoredemo;

public interface Coach {
    String getDailyWorkout();
}

Passo 2: Criar uma classe que implementa a interface

Crie a classe CricketCoach, marcando-a como um componente Spring:

package com.juhmaran.springcoredemo;

import org.springframework.stereotype.Component;

@Component
public class CricketCoach implements Coach {

    @Override
    public String getDailyWorkout() {
        return "Pratique boliche rápido por 15 minutos.";
    }
}

A anotação @Component indica que essa classe será gerenciada automaticamente pelo Spring (ou seja, se tornará um bean).

Passo 3: Criar o Controller REST

Crie a classe DemoController:

package com.juhmaran.springcoredemo;

import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public DemoController(Coach myCoach) {
        this.myCoach = myCoach;
    }
}

O @Autowired informa ao Spring para injetar automaticamente a dependência no construtor.
Se houver apenas um construtor, essa anotação é opcional.

Passo 4: Criar um endpoint GET

Adicione o método para expor a funcionalidade via URL:

package com.juhmaran.springcoredemo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public DemoController(Coach myCoach) {
        this.myCoach = myCoach;
    }

    @GetMapping("/dailyworkout")
    public String getDailyWorkout() {
        return myCoach.getDailyWorkout();
    }
}

Acesse no navegador: http://localhost:8080/dailyworkout

Você verá a mensagem: "Pratique boliche rápido por 15 minutos."

Dica: Habilitar recarregamento automático no IntelliJ

Se o DevTools não estiver recarregando automaticamente:

  1. Vá em File > Settings (ou Preferences no macOS).
  2. Acesse Advanced Settings:
    • Marque a opção "Allow auto-make...".
  3. Em Build, Execution, Deployment > Compiler:
    • Marque a opção "Build project automatically".

Com essas opções ativadas, alterações salvas no código serão recarregadas automaticamente.

36. Aviso da IDE – "No Usages" (Sem Uso)

Apareceu um aviso como "no usages" na sua IDE?
Não se preocupe, isso é comum ao trabalhar com Spring.

O Spring é um framework que funciona de forma dinâmica. Isso significa que muitas coisas acontecem em tempo de execução (ou seja, enquanto a aplicação está rodando). Por isso, sua IDE pode não conseguir identificar que uma determinada classe ou método está sendo usado, mesmo que esteja.

Exemplo:

A IDE pode mostrar um aviso dizendo que a classe CricketCoach não está sendo usada. Mas sabemos que ela está! Afinal, executamos o projeto e vimos a mensagem "Pratique boliche rápido por 15 minutos", que vem justamente dessa classe.

Então, por que a IDE acha que ela não está sendo usada?

Motivo:

  • No Spring, não chamamos diretamente a classe de implementação (CricketCoach) no nosso código.
  • Em vez disso, usamos uma interface (Coach) e deixamos o Spring escolher e injetar a implementação certa automaticamente.
  • Isso tudo acontece "nos bastidores", durante a execução da aplicação.
  • Como a IDE analisa o código estaticamente (sem rodar a aplicação), ela não consegue ver essa ligação dinâmica feita pelo Spring.

Conclusão:

Se você tiver certeza de que sua aplicação está funcionando corretamente e a classe está sendo usada pelo Spring, pode ignorar esse aviso da IDE.

Esse tipo de situação é comum em projetos que usam injeção de dependência. A IDE só não consegue acompanhar o que o Spring faz por trás das cortinas.

Claro! Abaixo está a reescrita do tópico 37, com uma linguagem mais clara e acessível para iniciantes, mantendo a numeração original:

37. Injeção por Construtor – O que acontece nos bastidores

Como o Spring processa sua aplicação

Veja os arquivos a seguir:

Arquivo: Coach.java

public interface Coach {
    String getDailyWorkout();
}

Arquivo: CricketCoach.java

@Component
public class CricketCoach implements Coach {
    @Override
    public String getDailyWorkout() {
        return "Pratique boliche rápido por 15 minutos!!!";
    }
}

Arquivo: DemoController.java

@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public DemoController(Coach myCoach) {
        this.myCoach = myCoach;
    }

    @GetMapping("/dailyworkout")
    public String getDailyWorkout() {
        return myCoach.getDailyWorkout();
    }
}

O que o Spring faz nos bastidores?

O Spring cuida da criação dos objetos e da injeção de dependência, ou seja, ele monta os componentes da aplicação para você, automaticamente. Por exemplo, o Spring executa algo como:

Coach theCoach = new CricketCoach();
DemoController demoController = new DemoController(theCoach);

Ou seja, ele cria um CricketCoach e injeta essa dependência no DemoController por meio do construtor.

Mas e se eu usasse new diretamente? Não é a mesma coisa?

Pode parecer que sim. Talvez você pense:

“Eu poderia fazer isso sozinho com new. Por que usar o Spring?”

Essa é uma pergunta válida. Mas o Spring vai muito além da simples criação de objetos com new. Ele oferece:

  • Inversão de Controle (IoC): você não precisa se preocupar com como os objetos são criados e conectados.
  • Injeção de Dependência (DI): o Spring injeta automaticamente os objetos certos nos lugares certos.

Esses conceitos, por si só, já ajudam a deixar o código mais limpo, organizado e fácil de manter.

E qual o verdadeiro poder do Spring?

Embora pareça simples agora, o Spring foi criado para aplicações grandes e complexas, especialmente em ambientes empresariais. Ele oferece muitos recursos avançados, como:

  • Acesso a banco de dados e controle de transações
  • Criação de APIs REST com Spring MVC
  • Segurança e autenticação
  • Integração com mensageria e serviços externos
  • Suporte a testes automatizados
  • E muito mais

Mais adiante no curso, vamos criar uma API REST completa com operações CRUD e acesso ao banco de dados. Aí sim você verá o poder real do Spring em ação.

Conclusão

Neste momento, pode parecer que usar new daria o mesmo resultado. Mas o Spring automatiza e gerencia tudo isso para você em aplicações reais, onde há dezenas ou centenas de componentes.

Então, fique tranquilo: estamos apenas começando. As partes mais interessantes e úteis do Spring ainda estão por vir!