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
: umRestController
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 classeDemoController
para ele. - Crie um pacote chamado
common
e mova as classesCoach
eCricketCoach
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
eCricketCoach
para esse novo pacoteutil
.
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.