Come eseguire la scansione di più percorsi utilizzando l'annotazione @ComponentScan?


90

Sto usando Spring 3.1 e sto avviando un'applicazione usando gli attributi @Configuratione @ComponentScan.

L'inizio effettivo è finito

new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);

Questa classe di configurazione è annotata con

@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass

e questo funziona bene. Tuttavia, vorrei essere più specifico sui pacchetti che ho scansionato, quindi ho provato.

@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass

Tuttavia, questo non riesce con errori che mi dicono che non è possibile trovare i componenti specificati utilizzando l' @Componentannotazione.

Qual è il modo corretto di fare ciò che cerco?

Grazie


Due risposte corrette date più o meno nello stesso momento per quanto ne so. Darò l'accettazione ad hage solo perché ha meno punti, ma grazie a entrambi.
Programming Guy

Se vi state chiedendo la stessa cosa per Kotlin versione controllare questo stackoverflow.com/a/62818187/7747942
Sylhare

Risposte:


161

@ComponentScan utilizza un array di stringhe, in questo modo:

@ComponentScan({"com.my.package.first","com.my.package.second"})

Quando fornisci più nomi di pacchetto in una sola stringa, Spring lo interpreta come un nome di pacchetto e quindi non riesce a trovarlo.


48

Esiste un'altra alternativa indipendente dai tipi per specificare una posizione del pacchetto di base come String. Vedi l'API qui , ma ho anche illustrato di seguito:

@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})

L'uso dello specificatore basePackageClasses con i riferimenti alla classe dirà a Spring di scansionare quei pacchetti (proprio come le alternative menzionate ), ma questo metodo è sia indipendente dai tipi che aggiunge il supporto IDE per il refactoring futuro - un enorme vantaggio nel mio libro.

Leggendo dall'API, Spring suggerisce di creare una classe o un'interfaccia marker no-op in ogni pacchetto che si desidera scansionare che non abbia altro scopo se non quello di essere utilizzato come riferimento per / da questo attributo.

IMO, non mi piacciono le classi marker (ma poi di nuovo, sono praticamente come le classi informazioni sui pacchetti) ma l'indipendenza dai tipi, il supporto IDE e la riduzione drastica del numero di pacchetti di base necessari da includere per questa scansione è, senza dubbio, un'opzione di gran lunga migliore.


Qualcuno potrebbe spiegare perché @ComponentScan ({"com.app", "com.controllers"}) non funziona per me ma @ComponentScan (basePackageClasses = {"com.controllers"}) funziona bene? Trovo noioso scrivere il nome di ogni classe
xaverras

3
Devi solo specificare una classe nel pacchetto, per il pacchetto che vuoi scansionare. Questa è nota come classe marker. Se è necessario scansionare un pacchetto più in alto nella gerarchia che non ha classi, spring suggerisce una tecnica che utilizza un'interfaccia "spring marker" o una classe finale definita in quel pacchetto esclusivamente allo scopo della scansione del pacchetto.
Prancer

17

Fornisci il nome del tuo pacchetto separatamente, richiede una String[]per i nomi dei pacchetti.

Invece di questo:

@ComponentScan("com.my.package.first,com.my.package.second")

Usa questo:

@ComponentScan({"com.my.package.first","com.my.package.second"})

10

Un altro modo per farlo è usare il basePackagescampo; che è un campo all'interno dell'annotazione ComponentScan.

@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})

Se guardi nell'annotazione ComponentScan .class dal file jar vedrai un campo basePackages che accetta un array di stringhe

public @interface ComponentScan {
String[] basePackages() default {};
}

Oppure puoi menzionare le classi esplicitamente. Che comprende una serie di classi

Class<?>[]  basePackageClasses

4

Si utilizza ComponentScan per eseguire la scansione di più pacchetti utilizzando

@ComponentScan({"com.my.package.first","com.my.package.second"})


1

assicurati di aver aggiunto questa dipendenza nel tuo pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Grazie dopo aver trascorso quasi mezz'ora questa era la dipendenza mancante
DvixExtract

1

Puoi anche utilizzare l'annotazione @ComponentScans:

@ComponentScans(value = { @ComponentScan("com.my.package.first"),
                          @ComponentScan("com.my.package.second") })

4
Considera l'
idea di

1

Io uso:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.