17‐Component Scanning - JulianeMaran32/Java-with-Spring-Boot GitHub Wiki

38. Varredura de Componentes (Component Scanning) – Visão Geral

O que é a varredura de componentes?

O Spring escaneia suas classes Java em busca de anotações especiais, como @Component, e registra automaticamente os beans (componentes) no contêiner do Spring.

Código-fonte Java

No nosso projeto, temos os seguintes arquivos:

  • SpringcoredemoApplication.java: classe principal da aplicação Spring Boot. Ela é criada automaticamente quando usamos o Spring Initializr.
  • DemoController.java: um RestController que criamos em um vídeo anterior.

Arquivo: SpringcoredemoApplication.java

package com.juhmaran.springcoredemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringcoredemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringcoredemoApplication.class, args);
	}
}

Essa anotação @SpringBootApplication ativa três recursos importantes:

  • Configuração automática
  • Varredura de componentes
  • Outras configurações adicionais

Essa anotação é composta por:

Anotação Descrição
@EnableAutoConfiguration Ativa a configuração automática do Spring Boot.
@ComponentScan Ativa a varredura de componentes no pacote atual e em subpacotes.
@Configuration Permite registrar beans extras com @Bean ou importar outras classes.

A classe SpringApplication inicializa sua aplicação: ela cria o Application Context, registra todos os beans encontrados e inicia o servidor embutido (como o Tomcat).

Entendendo melhor a varredura de componentes

Por padrão, o Spring Boot começa a varredura a partir do mesmo pacote da classe principal (a que tem o @SpringBootApplication) e também escaneia todos os subpacotes recursivamente.

Isso significa que você não precisa configurar o nome do pacote base manualmente, desde que tudo esteja organizado dentro do mesmo pacote raiz.

Exemplo:

Se sua aplicação principal estiver em:

com.juhmaran.springcoredemo

O Spring também vai escanear automaticamente:

com.juhmaran.springcoredemo.common
com.juhmaran.springcoredemo.controller
com.juhmaran.springcoredemo.entity
com.juhmaran.springcoredemo.repository
com.juhmaran.springcoredemo.rest
com.juhmaran.springcoredemo.service

Erro comum – Pacotes fora da estrutura principal

Se você criar pacotes fora do pacote principal, o Spring não vai escaneá-los automaticamente. Exemplo:

src/main/java/com/juhmaran/demo/utils

Esse pacote está fora da estrutura com.juhmaran.springcoredemo, portanto o Spring não vai escanear esse local automaticamente. Isso pode causar erros difíceis de identificar, como dependências que não são injetadas.

E se eu quiser escanear outros pacotes?

Se você quiser que o Spring escaneie pacotes fora do padrão, você pode informar isso manualmente, usando o parâmetro scanBasePackages:

@SpringBootApplication(
	scanBasePackages = {
		"com.juhmaran.springcoredemo",
		"com.juhmaran.utils",
		"org.exemplo.carrinho",
		"edu.universidade.sistema"
	})
public class SpringcoredemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringcoredemoApplication.class, args);
	}
}

Assim, você informa ao Spring exatamente quais pacotes ele deve escanear em busca de componentes.

Conclusão

  • O Spring escaneia suas classes para encontrar componentes automaticamente.
  • A anotação @SpringBootApplication facilita muito isso.
  • Por padrão, ele escaneia apenas o pacote principal e seus subpacotes.
  • Se quiser usar pacotes diferentes, você precisa configurá-los manualmente usando scanBasePackages.

39. Varredura de Componentes - Codificando - Parte 1

Organização Inicial do Projeto

Passos iniciais:

  • Pare todas as aplicações que estiverem em execução.
  • Feche todas as janelas abertas no IntelliJ ou outro editor.

Criar novos pacotes:

  • Crie um pacote chamado rest e mova a classe DemoController para ele.
  • Crie um pacote chamado common e mova as classes Coach e CricketCoach para esse novo pacote.

Esses novos pacotes são subpacotes do pacote principal da aplicação (com.juhmaran.springcoredemo). Por isso, eles serão detectados automaticamente pela varredura padrão de componentes do Spring Boot.

Executar a aplicação:

  • Após reorganizar as classes nos novos pacotes, execute novamente a aplicação.
  • Caso ocorra algum erro relacionado à configuração (ConfigurationClassParser), tente limpar e reconstruir o projeto (Build > Rebuild Project).
  • Acesse o endpoint no navegador: http://localhost:8080/dailyworkout.
  • Se tudo estiver funcionando corretamente, a resposta será exibida normalmente.

Conclusão:

A reorganização em subpacotes funcionou corretamente porque o Spring Boot, por padrão, faz a varredura de componentes a partir do pacote da classe principal da aplicação e de todos os seus subpacotes.

40. Varredura de Componentes - Codificando - Parte 2

Forçando um Erro de Propósito

Criar novo pacote:

  • Crie um pacote fora da estrutura principal, por exemplo: com.juhmaran.util.
  • Mova as classes Coach e CricketCoach para esse novo pacote util.

Problema: O pacote com.juhmaran.util não é subpacote do pacote principal da aplicação (com.juhmaran.springcoredemo). Por isso, o Spring Boot não irá escaneá-lo automaticamente.

Resultado ao executar:

  • A aplicação não irá iniciar.
  • A seguinte mensagem de erro será exibida:
APPLICATION FAILED TO START
...
Parameter 0 of constructor in com.juhmaran.springcoredemo.rest.DemoController required a bean of type 'com.juhmaran.util.Coach' that could not be found.

Solução: Definir Pacotes Base para Escaneamento

Para resolver isso, precisamos informar explicitamente ao Spring Boot quais pacotes ele deve escanear:

@SpringBootApplication(
        scanBasePackages = {"com.juhmaran.springcoredemo",
                            "com.juhmaran.util"})
public class SpringcoredemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringcoredemoApplication.class, args);
    }
}

Com isso, o Spring passa a reconhecer o pacote util como parte da varredura de componentes. Após essa alteração, a aplicação deve iniciar normalmente e o endpoint voltará a funcionar.

Conclusão

  • O Spring Boot realiza, por padrão, a varredura apenas no pacote da aplicação principal e seus subpacotes.
  • Para que outros pacotes (fora dessa hierarquia) também sejam escaneados, é necessário incluí-los manualmente usando o atributo scanBasePackages na anotação @SpringBootApplication.
  • É recomendável manter suas classes organizadas em subpacotes da aplicação principal sempre que possível, para aproveitar a varredura padrão do Spring Boot.