Pensez à définir un bean de type 'package' dans votre configuration [Spring-Boot]

110

Je reçois l'erreur suivante:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method setApplicant in webService.controller.RequestController required a bean of type 'com.service.applicant.Applicant' that could not be found.


Action:

Consider defining a bean of type 'com.service.applicant.Applicant' in your configuration.

Je n'ai jamais vu cette erreur auparavant, mais il est étrange que @Autowire ne fonctionne pas. Voici la structure du projet:

Interface du candidat

public interface Applicant {

    TApplicant findBySSN(String ssn) throws ServletException;

    void deleteByssn(String ssn) throws ServletException;

    void createApplicant(TApplicant tApplicant) throws ServletException;

    void updateApplicant(TApplicant tApplicant) throws ServletException;

    List<TApplicant> getAllApplicants() throws ServletException;
}

DemandeurImpl

@Service
@Transactional
public class ApplicantImpl implements Applicant {

private static Log log = LogFactory.getLog(ApplicantImpl.class);

    private TApplicantRepository applicantRepo;

@Override
    public List<TApplicant> getAllApplicants() throws ServletException {

        List<TApplicant> applicantList = applicantRepo.findAll();

        return applicantList;
    }
}

Maintenant, je devrais pouvoir simplement utiliser Autowire Applicant et pouvoir y accéder, mais dans ce cas, cela ne fonctionne pas lorsque je l'appelle dans mon @RestController:

@RestController
public class RequestController extends LoggingAware {

    private Applicant applicant;

    @Autowired
    public void setApplicant(Applicant applicant){
        this.applicant = applicant;
    }

    @RequestMapping(value="/", method = RequestMethod.GET)
    public String helloWorld() {

        try {
            List<TApplicant> applicantList = applicant.getAllApplicants();

            for (TApplicant tApplicant : applicantList){
                System.out.println("Name: "+tApplicant.getIndivName()+" SSN "+tApplicant.getIndSsn());
            }

            return "home";
        }
        catch (ServletException e) {
            e.printStackTrace();
        }

        return "error";
    }

}

------------------------ MISE À JOUR 1 -----------------------

J'ai ajouté

@SpringBootApplication
@ComponentScan("module-service")
public class WebServiceApplication extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebServiceApplication.class);
    }

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

}

et l'erreur est partie mais rien ne s'est produit. Cependant , lorsque je commentais sur tout ce qui touche à Applicantla RestControlleravant d'ajouter que @ComponentScan()j'ai pu retourner une chaîne la UI, ce qui signifie donc mon RestControllertravaillait, maintenant il est sauté. Je moche Whitelabel Error Pagemaintenant.

--------------------- MISE À JOUR 2 --------------------------- ---

J'ai ajouté le paquet de base du haricot dont il se plaignait. L'erreur lit:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method setApplicantRepo in com.service.applicant.ApplicantImpl required a bean of type 'com.delivery.service.request.repository.TApplicantRepository' that could not be found.


Action:

Consider defining a bean of type 'com.delivery.request.request.repository.TApplicantRepository' in your configuration.

J'ai ajouté @ComponentScan

@SpringBootApplication
@ComponentScan({"com.delivery.service","com.delivery.request"})
public class WebServiceApplication extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebServiceApplication.class);
    }

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

}

---------------------------- Mise à jour 3 -------------------- -

ajouter:

@SpringBootApplication
@ComponentScan("com")
public class WebServiceApplication extends SpringBootServletInitializer {

se plaint toujours de ma ApplicantImplclasse dans laquelle @Autowiresmon dépôt TApplicantRepositoryen elle.

Mike3355
la source
Où se trouve votre fichier de contexte d'application? Si vous n'en avez pas, vous devriez envisager de donner à Spring un indice avec des annotations comme @ComponentScan pour rendre tous les beans disponibles.
Mario Santini
@MarioSantini s'il vous plaît voir la mise à jour 1
Mike3355
Je suppose qu'après chaque mise à jour, il y a eu des changements dans les erreurs? Si possible, publiez la structure de votre projet et les journaux d'erreurs / stacktrace dans chaque cas. Il vaut mieux savoir "pourquoi" ces erreurs se sont produites, plutôt qu'un "quelque chose" qui a fait disparaître l'erreur. Sera également utile pour les autres qui rencontrent un problème similaire.
Ameen.M

Réponses:

202

Cela peut être dû au fait que le projet a été divisé en différents modules.

@SpringBootApplication
@ComponentScan({"com.delivery.request"})
@EntityScan("com.delivery.domain")
@EnableJpaRepositories("com.delivery.repository")
public class WebServiceApplication extends SpringBootServletInitializer {
Mike3355
la source
5
Cool. Mon projet est divisé en plusieurs modules. ComponentScan a résolu mon problème!
kholofelo Maloma
L'annotation ComponentScan résout mon problème mais @EnableAutoConfiguration ne le fait pas
JPL
En fait, EnableAutoConfiguration définit implicitement un «package de recherche» de base pour certains éléments et l'utilisation d'un package racine permet également d'utiliser l'annotation ComponentScan sans avoir besoin de spécifier un attribut basePackage. Et l'annotation @SpringBootApplication pourrait être utilisée si votre classe principale est dans le package racine
jpl
1
Cette solution m'a aidé avec cette erreur dans la version 2.0.4
manu muraleedharan
2
Oui, cela est dû au fait que le projet a été décomposé en différents modules. @EntityScanet @EnableJpaRepositoriesavec les bons noms de paquet a fonctionné pour moi.
Adi Sivasankaran
52

Il y a une chance ...
peut - être manquant @Service, @Repositoryannotation sur vos classes d'implémentation respectives.

CodeWorld
la source
2
Cela devrait être la réponse acceptée, simple et précise. Je vous remercie.
nightfury
1
A travaillé pour moi. Merci.
Okafor T Kosiso
1
Merci, il me manquait l'annotation
@Repository
1
Ouais, ça devrait être la réponse. Les réponses ci-dessus supposent simplement que l'analyse a échoué, ce qui est faux.
Sumit Badsara le
48

Votre classe de candidat n'est pas numérisée semble-t-il. Par défaut, tous les paquets commençant par la racine comme classe où vous avez mis@SpringBootApplication seront analysés.

supposons que votre mainclasse "WebServiceApplication" soit dans " com.service.something", alors tous les composants qui tombent sous " com.service.something" sont analysés, et "com.service.applicant " ne seront pas analysés.

Vous pouvez soit restructurer vos packages de telle sorte que "WebServiceApplication" tombe sous un package racine et que tous les autres composants deviennent une partie de ce package racine. Ou vous pouvez inclure@SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"}) etc de telle sorte que "TOUS" les composants soient scannés et initialisés dans le conteneur à ressort.

Mise à jour basée sur le commentaire

Si vous avez plusieurs modules gérés par maven / gradle, tout ce dont Spring a besoin est le package à analyser. Vous dites à spring de scanner "com.module1" et vous avez un autre module dont le nom de package racine est "com.module2", ces composants ne seront pas analysés. Vous pouvez même demander à Spring de scanner "com" qui analysera ensuite tous les composants dans " com.module1." et " com.module2."

Ameen.M
la source
Mon projet est la structure est différents modules. Par exemple, les services auront leur propre module et build.gradle. Ces build.gradlenoms de module sont ajoutés au dependenciesmodule avec la méthode main. Par conséquent, quand vous avez vu @ComponentScan("module-service")que je pensais que cela fonctionnerait. Cependant à l'intérieur module-servicea un paquet. Alors ma question à quoi cela ressemblerait-il? Dois-je simplement nommer le nom du package ou le nom du module ou les deux?
Mike3355
Peu importe si les packages appartiennent à des modules différents. Les emballages dans lesquels les composants doivent être scannés doivent être spécifiés pour spring. Vous pouvez donner tous les noms de package "root" de tous vos modules dans l'attribut "scanBasePackages" .. Et tous ses "packages" qui doivent être mentionnés, pas les modules.
Ameen.M
Avez-vous fait ce que vous avez dit et l'erreur a disparu, mais pour se plaindre seulement d'un autre paquet. Naturellement, je l'ai ajouté à la liste mais cela ne disparaîtra pas. Je l'ai implémenté comme ceci:@SpringBootApplication(scanBasePackages= {"com.delivery.service","com.delivery.request"})
Mike3355
Je viens de le faire @SpringBootApplication(scanBasePackages= "com")et il se plaint du référentiel JPA. Merci beaucoup. Je ne savais pas que Spring analyserait tous les paquets commençant par "com" si vous faites ce qui précède.
Mike3355
23

Fondamentalement, cela se produit lorsque vous avez votre application de classe dans "un autre package". Par exemple:

com.server
 - Applicacion.class (<--this class have @ComponentScan)
com.server.config
 - MongoConfig.class 
com.server.repository
 - UserRepository

Je résous le problème avec cela dans Application.class

@SpringBootApplication
@ComponentScan ({"com.server", "com.server.config"})
@EnableMongoRepositories ("com.server.repository") // this fix the problem

Une autre manière moins élégante est de: mettre toutes les classes de configuration dans le même package.

Carlos Marcano
la source
2
En fait, vous n'avez pas besoin de spécifier @ComponentScandans le scénario ci-dessus. Parce que votre Application.class(qui a l' @SpringBootApplicationannotation) est placé dans com.serverlequel est de toute façon la racine pour les deux com.server.configainsi que pour com.server.repository.
Ameen.M
@ Ameen.M C'est ma question exacte, pourquoi cela ne peut toujours pas être résolu et pourquoi cela nécessite-t-il un scan explicite pour les repos mongo utilisant @EnableMongoRepositories?
Karthikeyan
10

Dans mon cas, j'ai eu une terrible erreur. je mets@Service place l'interface de service.

Pour résoudre ce problème, j'ai mis @Servicesur l'implémentation du fichier de service et cela a fonctionné pour moi.

Mohammad Falahi
la source
Pareil pour moi. Merci
Manta
7

Si un bean est dans le même package dans lequel il est @Autowired, cela ne causera jamais un tel problème. Cependant, les beans ne sont pas accessibles par défaut à partir de différents packages. Pour résoudre ce problème, procédez comme suit:

  1. Importez les éléments suivants dans votre classe principale:
    import org.springframework.context.annotation.ComponentScan;
  2. ajoutez une annotation sur votre classe principale:
@ComponentScan(basePackages = {"your.company.domain.package"})
public class SpringExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringExampleApplication.class, args);
    }
}
ASHWANI PANDEY
la source
5

Je pense que vous pouvez le simplifier en annotant votre référentiel avec @Repository, puis il sera activé automatiquement par Spring Framework.

Tushar Saha Chowdhury
la source
4

Dans mon cas, ces deux options ont fonctionné.

  1. in //@ComponentScan ({"myapp", "myapp.resources","myapp.services"}) inclure également le package qui contient le Application.classdans la liste, ou

  2. Ajoutez simplement @EnableAutoConfiguration; il reconnaît automatiquement tous les haricots de printemps.

Sriharsha grv
la source
3

Cela peut également se produire si vous utilisez Lombok et que vous ajoutez les champs @RequiredArgsConstructoret @NonNullfor mais que certains de vos champs ne doivent pas être injectés dans le constructeur. Ce n'est qu'une des possibilités d'obtenir la même erreur.

le paramètre 0 nécessitait un bean de type MissingBeanName introuvable

Dans mon cas, l'erreur m'a indiqué dans quel contrôleur se trouvait le problème, après la suppression de @NonNulll'application a bien démarré

Dawid Gorczyca
la source
3

J'ai rencontré un problème familier dans mon projet multi-module Maven avec Spring Boot 2. Le problème était lié à la dénomination de mes packages dans les sous-modules Maven.

@SpringBootApplication incapsule un grand nombre de composants tels que - @ComponentScan, @EnableAutoConfiguration, jpa-repositories, json-serialization et ainsi de suite. Et il place @ComponentScan dans com. *******. Space package. Cette partie des packages com. *******. Space doit être commune à tous les modules.

Pour le réparer:

  1. Vous devez renommer tous les packages de modules. D'autres mots que vous deviez avoir dans tous les packages de tous les modules Maven - la même partie parent. Par exemple - com. *******. Space
  2. Vous devez également déplacer votre point d'entrée vers ce package - com. *******. Space
alexis_druzik
la source
2

J'ai cherché une réponse en ligne mais il semble qu'il n'y ait pas de solution unique à mon cas: au tout début, tout fonctionne bien comme suit:

@Slf4j
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GroupService {
    private Repository repository;
    private Service service;
}

Ensuite, j'essaie d'ajouter une carte pour mettre en cache quelque chose et cela devient ceci:

@Slf4j
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GroupService {
    private Repository repository;
    private Service service;
    Map<String, String> testMap;
}

Boom!

Description:

Parameter 4 of constructor in *.GroupService required a bean of type 'java.lang.String' that could not be found.


Action:

Consider defining a bean of type 'java.lang.String' in your configuration.

J'ai supprimé le @AllArgsConstructor(onConstructor = @__(@Autowired))et ajouter @Autowiredpour chacun repositoryet servicesauf le Map<String, String>. Cela fonctionne comme avant.

@Slf4j
@Service
public class SecurityGroupService {
    @Autowired
    private Repository repository;
    @Autowired
    private Service service;
    Map<String, String> testMap;
}

J'espère que cela pourrait être utile.

Entendre
la source
2

Cela a fonctionné pour moi après avoir ajouté l'annotation ci-dessous dans l'application:

@ComponentScan({"com.seic.deliveryautomation.mapper"})

J'obtenais l'erreur ci-dessous:

"paramètre 1 du constructeur dans requis un bean de type mapper qui n'a pas pu être trouvé:

Aime Kumar
la source
2

L'annotation @Configuration résoudra simplement l'erreur

oludamilare olukotun
la source
2

Vous obtiendrez également cette erreur si vous définissez accidentellement le même bean dans deux classes différentes. Cela m'est arrivé. Le message d'erreur était trompeur. Lorsque j'ai supprimé le bean supplémentaire, le problème a été résolu.

Ross Mills
la source
1
@SpringBootApplication
@MapperScan("com.developer.project.mapper")

public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
développeur07
la source
1

Cela peut se produire si la classe @Service est marquée comme abstraite.

Ariel
la source
1

Si votre dépendance de classe est gérée par Spring, ce problème peut se produire si nous avons oublié d'ajouter le constructeur arg par défaut / vide dans notre classe POJO.

Arif Khan
la source
1

Cela pourrait aider quelqu'un. J'ai eu le même problème, le même message d'erreur, le même tout. J'ai essayé des solutions d'autres réponses, je n'ai pas aidé jusqu'à ce que je me rende compte que le bean que j'utilise porte le même nom que celui qui est en fait câblé automatiquement. Cela s'est passé au milieu du refactor, j'ai donc dû renommer la classe, ce qui a abouti de manière positive. À votre santé

Staxx
la source
1

J'ai fait face au même problème. Le référentiel Mongo DB a été identifié par Spring Boot, mais il ne créait pas de Bean pour une interface de référentiel qui étendait le référentiel mongo.

Le problème dans mon cas était une spécification de version incorrecte dans maven pom pour "spring + mango". J'ai changé l'identifiant de groupe de l'artefact et tout a fonctionné comme par magie. aucune annotation nécessaire car Spring Boot s'est occupé de tout.

Au cours de ma résolution de problème, j'étais partout sur le Web à la recherche de solutions et j'ai réalisé que ce problème était en fait lié à la configuration du projet, toute personne confrontée à ce problème devrait d'abord vérifier la configuration de son projet et activer le débogage à partir du printemps pour obtenir plus de détails sur l'échec et porter une attention particulière à où exactement dans le processus, la création a échoué.

user13650952
la source
0

Dans mon cas, cette erreur apparaît car mon importation était incorrecte, par exemple, en utilisant le ressort, l'importation apparaît automatiquement:

import org.jvnet.hk2.annotations.Service;

mais j'avais besoin de:

import org.springframework.stereotype.Service;
Washington da Silva
la source
0

J'ai eu un cas où j'ai besoin d'injecter RestTemplate dans une classe de service. Toutefois, le RestTemplate ne peut pas être récupéré par la classe de service. Ce que j'ai fait, c'est de créer une classe de wrapper sous le même package que l'application principale et de marquer le wrapper comme composant et de faire passer automatiquement ce composant dans la classe de service. Problème résolu. j'espère que cela fonctionne aussi pour vous

user11976602
la source
0

Mon erreur était que j'avais inclus:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

au lieu de:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
user1441323
la source
0

Je pense qu'il vous manque l'annotation @Bean dans votre RequestController

Ajoutez le Bean dans votre fichier, cela a résolu mon problème
J'ai obtenu cette solution pendant que j'apprenais Spring Boot à partir de tutorialspoint

private Applicant applicant;

@Bean 
public Applicant applicant() { 
    return new Applicant(); 
}
user3709901
la source
0

L'ajout de la dépendance Spring Boot Data JPA Starter a résolu le problème pour moi.

Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

Gradle

compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.2.6.RELEASE'

Ou vous pouvez aller directement ici

Johny Thomas Kariath
la source
Cela ne s'applique en fait pas dans ce cas. Il demande les détails de connexion à la base de données (Échec de la configuration d'une source de données: l'attribut 'url' n'est pas spécifié et aucune source de données intégrée n'a pu être configurée.). Dans une situation où je veux tester manuellement sans interagir avec la base de données, cela ne fonctionnera pas.
Thomas Okonkwo
0

Si vous utilisez, interfacevous pouvez étendre CrudRepository<Applicant,Long>avec une @Repositoryannotation.

zawhtut
la source
0

Le problème peut également apparaître lorsque vous utilisez par exemple @EnableMongoRepositories(YOUR_MONGO_REPOSITORIES_PACKAGE) et que vous avez ultérieurement renommé le nom du package ou l'avez déplacé à un autre endroit.

Très souvent confronté à cela dans un projet maven multi-module et spring boot

redoff
la source
0

Il est possible que vous essayiez de @autowired une interface avant d'implémenter l'interface.

exemple de solution:

    **HomeController.java**
    class HomeController{

      @Autowired
      UserService userService;
    .....
    }
----------------------------------------------------------------------
    **UserService.java** 
    public interface UserService {
        User findByUsername(String username);
    .....
    }
-----------------------------------------------------------------------
     **UserServiceImpl.java**
     @Service
     public class UserServiceImpl implements UserService{

         public User findByUsername(String username) {
           return userDao.findByUsername(username);
         }
        ....
      }

<i>This is not italic</i>, and [this is not a link](https://example.com)
biddut
la source
0

Supprimez la configuration de type d'annotation comme @Service de la méthode d'exécution de thread.

@Service, @Component
Sandun Susantha
la source
0

Essayez de configurer la structure du projet comme indiqué ci-dessous:

Mettez tous les packages repo, service, packages dans le package enfant du package principal:

package com.leisure.moviemax;  //Parent package
        
@SpringBootApplication
@PropertySource(value={"classpath:conf.properties"})
    
public class MoviemaxApplication implements CommandLineRunner {
        
package com.leisure.moviemax.repo; //child package

@Repository
public interface UsrRepository extends JpaRepository<UserEntity,String> {
Barani r
la source
0

rappel que spring ne scanne pas le monde, il utilise une analyse ciblée, ce qui signifie tout ce qui se trouve sous le paquet où springbootapplication est stockée. par conséquent, cette erreur «Pensez à définir un bean de type 'package' dans votre configuration [Spring-Boot]» peut apparaître car vous avez des interfaces de services dans un autre package springbootapplication.

pop-corn
la source