Analyse des composants de différents modules maven/Pots au Printemps de Démarrage de l'application
J'ai deux modules Maven.
La première, appelée "application", contient les spring boot
Application de classe qui ne contient ces lignes:
package org.example.application;
@SpringBootApplication
@ComponentScan({"org.example.model", "org.example"})
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
Dans le même module Maven et paquet, org.example.application
, j'ai un RestController
qui utilise un Component
qui à son tour utilise les composants de l'autre Maven module décrit ci-dessous.
L'autre Maven module, appelé "modèle", contient les spring boot
composants (crud-dépôts, d'entités, etc). Toutes ces classes sont sous la même structure de paquet que le premier module Maven ( org.example
), mais dans des sous-paquets de cela, comme org.example.model.entities
, org.example.model.repositories
etc.
Ainsi, le flux est comme ceci:
Maven module application
dans le paquet org.exemple:
SpringBootApplication -> RestController -> MyComponent
Et les composants qui doivent être autocâblés dans MyComponent
sont ceux dans la model
Maven module sous le package org.example.model
.
Mais quand je lance l'application, j'ai juste le message d'erreur:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field myRepository in org.example.MyComponent required a bean of type 'org.example.model.repositories.MyRepository' that could not be found.
Action:
Consider defining a bean of type 'org.example.model.repositories.MyRepository' in your configuration.
org.example.model.repositories.MyRepository
n'existe pas dans Maven module "modèle", mais ne peut pas être trouvé par le SpringBootApplication classe!
Comme vous pouvez le voir, j'ai essayé de définir explicitement l'analyse des composants:
@ComponentScan({"org.example.model", "org.example"})
mais cela ne semble pas aider.
Donc, qu'ai-je fait de mal?
Vous devez vous connecter pour publier un commentaire.
La première chose que vous devriez me demande : pourquoi avez-vous déclarer
@ComponentScan
alors que l'un des objectif de@SpringBootApplication
est (entre autres choses) pour activer le composant d'analyse ?De Printemps de Démarrage de la documentation :
Noter que lorsque la classe de votre Ressort de Démarrage de l'Application, vous déclarez
@ComponentScan
pour spécifier une valeurbasePackages
, il remplace lebasePackages
utilisé par défaut par@SpringBootApplication
qui est le paquet actuel où la classe réside. Afin d'avoir une base de package le package du Printemps de Démarrage de la classe d'Application et les modules supplémentaires qui étaient manquantes, vous devez définir explicitement eux.Outre
basePackages
est récursive. Afin de permettre l'analyse à la fois pour les classes de localisation dans l'"org.example"
et"org.example.model"
paquets, en précisant"org.example"
est assez"org.example.model"
est un sous-paquet.Essayer ça :
Ou alternativement :
Quand spécifier @EnableJpaRepositories/@ComponentScan/scanBasePackages, au Printemps de Démarrage de l'Application ?
Que la conception de votre Ressort de Démarrage de l'application de mise en page, vous avez deux cas de figure :
1) cas (à favoriser) où vous utilisez un package de mise en page qui fournit la configuration automatique du Printemps de Démarrage avec zéro configuration.
Pour résumer : si vos classes annotées avec le Printemps Bean stéréotypes :
@Component
,@Repositories
,@Repositories
,... sont situés dans le même paquet ou un sous-ensemble du Ressort de Démarrage de la classe d'Application, déclarant seulement@SpringBootApplication
est tout ce dont vous avez besoin.2) (à éviter) où vous n'utilisez pas un package de mise en page qui fournit la configuration automatique du Printemps de Démarrage avec zéro configuration.
Cela signifie généralement que vous avez candidat classes d'analyse qui ne sont pas dans l'ensemble (ou sous-ensemble) de votre classe annotée avec
@SpringBootApplication
.Dans ce cas, vous ajoutez la
scanBasePackages
attribut ou ajouter@ComponentScan
pour indiquer les paquets de scanner.Mais en outre, si vos dépôts ne sont pas situés dans un emballage ou un sous-ensemble de votre classe annotée avec
@SpringBootApplication
, quelque chose d'autre doit être déclaré comme :@EnableJpaRepositories(="packageWhereMyRepoAreLocated")
Voici la documentation sur cette partie (l'emphase est mienne) :
Exemples
1) cas (à favoriser) où vous utilisez un package de mise en page qui fournit la configuration automatique du Printemps de Démarrage avec zéro configuration.
Avec un Ressort de Démarrage de l'application déclaré dans le
org.example
paquet, et toutes les classes de haricots (Dépôts inclus) déclarés dans le même paquet ou un sous-ensemble deorg.example
, la déclaration suivante est assez pour le Printemps de Démarrage de l'application :Les dépôts pourrait être situé dans la
org.example.repository
package tel que :et
Les contrôleurs peuvent être situés dans le
org.example.controller
package :et donc pour...
2) (à éviter) où vous n'utilisez pas un package de mise en page qui fournit la configuration automatique du Printemps de Démarrage avec zéro configuration.
Avec un Ressort de Démarrage de l'application déclaré dans le
org.example.application
paquet, et pas tous les types de haricots (Dépôts inclus) déclarés dans le même paquet ou un sous-ensemble deorg.example.application
, la déclaration suivante sera nécessaire pour le Printemps de Démarrage de l'application :Et les classes de haricots pourrait être comme ci-dessous.
Les dépôts qui peuvent venir de l'extérieur d'un POT pourrait être situé dans la
org.thirdparty.repository
package tel que :et
Les contrôleurs peuvent être situés dans le
org.example.controller
package :et donc pour...
Conclusion : la définition du Printemps de Démarrage de l'application dans le package de base de votre espace de noms est vraiment encouragés à faire le Printemps de configuration de Démarrage aussi simple que possible.
SpringBootApplication
classe réside dans leorg.example.application
paquet. Si je déplace leSpringBootApplication
pour le packageorg.example
, alors il fonctionne. Mais je ne comprends pas pourquoi il ne peut pas être sousorg.example.application
quand je rendre explicite le composant d'analyse pour analyser le tout sousorg.example
, comme@ComponentScan({"org.example.model", "org.example"})
.@SpringBootApplication
qui provoque la numérisation par défaut package le package courantorg.example.application
que vous ne spécifiez passcanBasePackages
attribut? Pouvez-vous essayer à nouveau avec@SpringBootApplication(scanBasePackages={"org.example"})
comme indiqué dans ma réponse? Et supprimer@ComponentScan
qui est redondant. Il devrait fonctionner.@Enable*Repositories
avec le paquet, ou tout simplement ajouter le scanBasePackages attribut SpringBootApplication, qui s'applique à la composante d'analyse, de Printemps référentiel de Données, d'une entité de numérisation etc.@Repositories
sont inclus dans le même paquet (ou un sous-ensemble) de votre@EnableAutoConfiguration
classe. Si vous les classes de dépôt ne sont pas situés dans le forfait ou sous-paquetage de votre ressort de démarrage de la classe app, ce comportement est normal.