Considera l'idea di definire un bean di tipo "pacchetto" nella tua configurazione [Spring-Boot]


109

Ricevo il seguente errore:

***************************
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.

Non ho mai visto questo errore prima, ma è strano che @Autowire non funzioni. Ecco la struttura del progetto:

Interfaccia richiedente

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;
}

ApplicantImpl

@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;
    }
}

Ora dovrei essere in grado di eseguire solo Autowire Richiedente ed essere in grado di accedere, tuttavia in questo caso non funziona quando lo chiamo nel mio @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";
    }

}

------------------------ AGGIORNAMENTO 1 -----------------------

Ho aggiunto

@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);
    }

}

e l'errore è andato via ma non è successo niente. Tuttavia quando ho commentato tutto ciò che riguarda Applicantla RestControllerprima di aggiungere @ComponentScan()ero in grado di restituire una stringa del UI, quindi significa il mio RestControllerfunzionava, ora è in fase saltato. Sono brutto Whitelabel Error Pageadesso.

--------------------- AGGIORNAMENTO 2 --------------------------- ---

Ho aggiunto il pacchetto base del fagiolo di cui si lamentava. Letture di errore:

***************************
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.

Ho aggiunto @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);
    }

}

---------------------------- Aggiornamento 3 -------------------- -

aggiungendo:

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

si lamenta ancora della mia ApplicantImplclasse che il @Autowiresmio repo TApplicantRepositoryin esso.


Dov'è il tuo file di contesto dell'applicazione? Se non ne hai uno, dovresti considerare di dare a Spring qualche suggerimento con annotazioni come @ComponentScan per rendere disponibili tutti i bean.
Mario Santini

@MarioSantini, consultare l'aggiornamento 1
Mike3355

Presumo che dopo ogni aggiornamento ci siano stati cambiamenti negli errori? Se possibile, pubblica la struttura del tuo progetto e in ogni caso i log degli errori / stacktrace .. È meglio sapere "Perché" si sono verificati questi errori, piuttosto che un "qualcosa" che ha fatto scomparire l'errore. Sarà utile anche per gli altri che incontrano un problema simile.
Ameen.M

Risposte:


201

Potrebbe essere perché il progetto è stato suddiviso in diversi moduli.

@SpringBootApplication
@ComponentScan({"com.delivery.request"})
@EntityScan("com.delivery.domain")
@EnableJpaRepositories("com.delivery.repository")
public class WebServiceApplication extends SpringBootServletInitializer {

5
Freddo. Il mio progetto è diviso da una serie di moduli. ComponentScan ha risolto il mio problema!
kholofelo Maloma

L'annotazione ComponentScan risolve il mio problema ma @EnableAutoConfiguration no
jpl

Infatti, EnableAutoConfiguration definisce implicitamente un "pacchetto di ricerca" di base per determinati elementi e l'utilizzo di un pacchetto radice consente anche di utilizzare l'annotazione ComponentScan senza la necessità di specificare un attributo basePackage. E l'annotazione @SpringBootApplication potrebbe essere utilizzata se la tua classe principale è nel pacchetto radice
jpl

1
Questa soluzione mi ha aiutato con questo errore nella versione 2.0.4
manu muraleedharan

2
Sì, è dovuto al fatto che il progetto è stato suddiviso in diversi moduli. @EntityScane @EnableJpaRepositoriescon i nomi dei pacchetti giusti ha funzionato per me.
Adi Sivasankaran

52

V'è una possibilità ...
Potrebbe mancare @Service, @Repositoryl'annotazione sulle vostre rispettive classi di implementazione.


2
Questa dovrebbe essere la risposta accettata, semplice e precisa. Grazie.
furia notturna il

1
Ha funzionato per me. Grazie.
Okafor T Kosiso,

1
Grazie, mi mancava l'annotazione
@Repository

1
Sì, questa dovrebbe essere la risposta. Le risposte precedenti presumono semplicemente che la scansione non sia riuscita, il che è sbagliato.
Sumit Badsara,

48

La tua classe candidato non è stata scansionata, a quanto pare. Per impostazione predefinita, @SpringBootApplicationverranno esaminati tutti i pacchetti che iniziano con la radice come classe in cui è stato inserito .

supponiamo che la tua mainclasse "WebServiceApplication" sia in " com.service.something", quindi tutti i componenti che rientrano in " com.service.something" vengono esaminati e " com.service.applicant" non verranno esaminati.

È possibile ristrutturare i pacchetti in modo tale che "WebServiceApplication" rientri in un pacchetto root e tutti gli altri componenti diventino parte di quel pacchetto root. Oppure è possibile includere @SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"})ecc. In modo che i componenti "TUTTI" vengano scansionati e inizializzati nel contenitore della molla.

Aggiorna in base al commento

Se si dispone di più moduli gestiti da maven / gradle, tutto ciò di cui la primavera ha bisogno è il pacchetto da scansionare. Dite a spring di scansionare "com.module1" e avete un altro modulo che ha il nome del pacchetto radice "com.module2", quei componenti non verranno scansionati. Puoi anche dire a spring di scansionare "com" che quindi scansionerà tutti i componenti in " com.module1." e " com.module2."


Il mio progetto è la struttura è diversi moduli. Ad esempio, i servizi avranno il proprio modulo e build.gradle. Questi build.gradlenomi di modulo vengono aggiunti al dependenciesdel modulo con il metodo principale. Quindi quando hai visto è @ComponentScan("module-service")quello che ho pensato avrebbe funzionato. Tuttavia all'interno module-serviceha un pacchetto. Quindi la mia domanda come sarebbe? Devo solo nominare il nome del pacchetto o il nome del modulo o in qualche modo entrambi?
Mike3355

Non importa se i pacchetti rientrano in moduli diversi. I pacchetti in cui devono essere scansionati i componenti dovrebbero essere specificati per la primavera. Puoi dare tutti i nomi dei pacchetti "root" di tutti i tuoi moduli nell'attributo "scanBasePackages". E sono tutti i "pacchetti" che devono essere menzionati, non i moduli.
Ameen.M

Hai fatto quello che hai detto e l'errore è andato via, ma solo per lamentarti dell'ennesimo pacchetto. Naturalmente l'ho aggiunto alla lista ma non andrà via. L'ho implementato in questo modo:@SpringBootApplication(scanBasePackages= {"com.delivery.service","com.delivery.request"})
Mike3355

L'ho appena fatto @SpringBootApplication(scanBasePackages= "com")e si lamenta del repository JPA. Grazie mille. Non sapevo che la primavera scansionerebbe tutti i pacchetti che iniziano con "com" se si esegue quanto sopra.
Mike3355

23

Fondamentalmente questo accade quando hai la tua applicazione di classe in "un altro pacchetto". Per esempio:

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

Risolvo il problema con questo in Application.class

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

Un altro modo meno elegante è: mettere tutte le classi di configurazione nello stesso pacchetto.


2
Infatti, non è necessario specificare @ComponentScannello scenario sopra. Perché il vostro Application.class(che ha l' @SpringBootApplicationannotazione) viene posto in com.servercui è in ogni caso la radice sia com.server.configcosì come com.server.repository.
Ameen.M

@ Ameen.MQuesta è la mia domanda esatta, perché non è ancora possibile risolverlo e perché richiede una scansione esplicita per i repository di mongo che utilizzano @EnableMongoRepositories?
Karthikeyan

10

Nel mio caso ho avuto un terribile errore. Accetto @Servicel'interfaccia del servizio.

Per risolverlo, ho inserito @Servicel'implementazione del file di servizio e ha funzionato per me.


Stessa cosa per me. Grazie
Manta

7

Se un bean si trova nello stesso pacchetto in cui è @Autowired, non causerà mai un problema del genere. Tuttavia, i bean non sono accessibili da pacchetti diversi per impostazione predefinita. Per risolvere questo problema, segui questi passaggi:

  1. Importa quanto segue nella tua classe principale:
    import org.springframework.context.annotation.ComponentScan;
  2. aggiungi annotazioni sulla tua classe principale:
@ComponentScan(basePackages = {"your.company.domain.package"})
public class SpringExampleApplication {

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

5

Penso che tu possa semplificarlo annotando il tuo repository con @Repository, quindi verrà abilitato automaticamente da Spring Framework.


4

Nel mio caso queste due opzioni hanno funzionato.

  1. in //@ComponentScan ({"myapp", "myapp.resources","myapp.services"}) includere anche il pacchetto che contiene Application.classnell'elenco, o

  2. Aggiungi semplicemente @EnableAutoConfiguration; riconosce automaticamente tutti i fagioli primaverili.


3

Questo può accadere anche se stai usando Lombok e aggiungi i campi @RequiredArgsConstructore @NonNullper ma alcuni dei tuoi campi non devono essere iniettati nel costruttore. Questa è solo una delle possibilità per ottenere lo stesso errore.

il parametro 0 richiedeva un bean di tipo MissingBeanName che non è stato trovato

Nel mio caso l'errore mi ha detto in quale controller si trovava il problema, dopo aver rimosso @NonNulll'applicazione è iniziata correttamente


3

Ho affrontato un problema familiare nel mio progetto multimodulo Maven con Spring Boot 2. Il problema era correlato alla denominazione dei miei pacchetti nei moduli Maven secondari.

@SpringBootApplication incapsula molti componenti come - @ComponentScan, @EnableAutoConfiguration, jpa-repository, json-serialization e così via. E inserisce @ComponentScan nel pacchetto com. *******. Space. Questa parte di packages com. *******. Space deve essere comune a tutti i moduli.

Per ripararlo:

  1. Dovresti rinominare tutti i pacchetti del modulo. Altre parole che dovevi avere in tutti i pacchetti in tutti i moduli Maven - la stessa parte genitore. Ad esempio - com. *******. Space
  2. Inoltre è necessario spostare il punto di ingresso in questo pacchetto - com. *******. Space

2

Ho cercato online una risposta ma sembra che non ci sia una soluzione adeguata al mio caso: all'inizio, tutto funziona bene come segue:

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

Quindi sto cercando di aggiungere una mappa per memorizzare qualcosa nella cache e diventa questo:

@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.

Ho rimosso @AllArgsConstructor(onConstructor = @__(@Autowired))e aggiunto @Autowiredper ciascuno repositorye servicetranne il Map<String, String>. Funziona come prima.

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

Spero che questo possa essere utile.


2

Ha funzionato per me dopo aver aggiunto l'annotazione di seguito nell'applicazione:

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

Stavo ottenendo il seguente errore:

"il parametro 1 del costruttore richiedeva un bean di tipo mapper che non è stato trovato:



2

Riceverai questo errore anche se definisci accidentalmente lo stesso bean in due classi diverse. È successo a me. Il messaggio di errore era fuorviante. Quando ho rimosso il bean in più, il problema è stato risolto.


1
@SpringBootApplication
@MapperScan("com.developer.project.mapper")

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

1

Ciò può accadere se la classe @Service è contrassegnata come astratta.


1

Se la dipendenza dalla tua classe viene gestita entro Spring, questo problema può verificarsi se ci dimentichiamo di aggiungere un costruttore arg predefinito / vuoto all'interno della nostra classe POJO.


1

Potrebbe aiutare qualcuno. Ho avuto lo stesso problema, lo stesso messaggio di errore, lo stesso tutto. Ho provato soluzioni da altre risposte, non ho aiutato fino a quando non mi sono reso conto che il bean che sto usando ha lo stesso nome di quello che è stato effettivamente cablato. È successo durante il refactoring, quindi ho dovuto rinominare la classe, il che è risultato positivo. Saluti


1

Ho affrontato lo stesso problema. Il repository Mongo DB è stato identificato da Spring Boot, ma non stava creando Bean per un'interfaccia del repository che estendesse il repository mongo.

Il problema nel mio caso era la specifica della versione errata in maven pom per "spring + mango". Ho cambiato l'ID di gruppo del manufatto e tutto ha funzionato come per magia. nessuna annotazione necessaria poiché lo stivale a molla si è preso cura di tutto.

Durante la risoluzione del problema, ero dappertutto sul web alla ricerca di soluzioni e mi sono reso conto che questo problema è in realtà correlato alla configurazione del progetto, chiunque affronti questo problema dovrebbe prima controllare la configurazione del progetto e abilitare il debug dalla primavera per ottenere maggiori dettagli sul fallimento e prestare molta attenzione a dove esattamente nel processo, la creazione è fallita.


0

Nel mio caso questo errore appare perché la mia importazione era sbagliata, ad esempio, usando la primavera, l'importazione appare automaticamente:

import org.jvnet.hk2.annotations.Service;

ma avevo bisogno di:

import org.springframework.stereotype.Service;

0

Ho avuto un caso in cui ho bisogno di iniettare RestTemplate in una classe di servizio. Tuttavia, RestTemplate non può essere prelevato dalla classe di servizio. Quello che ho fatto è creare una classe wrapper nello stesso pacchetto dell'applicazione principale e contrassegnare il wrapper come Component e autowire questo componente nella classe di servizio. Problema risolto. spero che funzioni anche per te


0

Il mio errore è stato che avevo incluso:

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

invece di:

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

0

Penso che ti manchi l'annotazione @Bean nel tuo RequestController

Aggiungi il fagiolo nel tuo file, questo ha risolto il mio problema
Ho ottenuto questa soluzione mentre stavo imparando Spring Boot da tutorialspoint

private Applicant applicant;

@Bean 
public Applicant applicant() { 
    return new Applicant(); 
}

0

L'aggiunta della dipendenza Spring Boot Data JPA Starter ha risolto il problema per me.

Esperto di

<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'

Oppure puoi andare direttamente qui


Questo in realtà non si applica in questo caso. Richiede i dettagli di connessione al database (Impossibile configurare un'origine dati: l'attributo 'url' non è specificato e non è possibile configurare l'origine dati incorporata). In una situazione in cui voglio testare manualmente senza interagire con il database, questo non funzionerà.
Thomas Okonkwo

0

Se usi interfacepuoi estendere CrudRepository<Applicant,Long>con @Repositoryannotazione.


0

Il problema può anche apparire quando usi per esempio @EnableMongoRepositories(YOUR_MONGO_REPOSITORIES_PACKAGE)e in seguito hai rinominato il nome del pacchetto o spostato in un altro posto.

Molto spesso l'ho affrontato all'interno di un progetto maven multi-modulo e di un avvio a molla


0

V'è una possibilità che si sta tentando di @autowired un'interfaccia prima di implementare l'interfaccia.

soluzione di esempio:

    **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)

0

Rimuovi la configurazione del tipo di annotazione come @Service dal metodo di esecuzione del thread.

@Service, @Component

0

Prova a configurare la struttura del progetto come indicato di seguito:

Metti tutti i repository, i servizi, i pacchetti nel pacchetto figlio del pacchetto principale:

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> {

0

ricorda che la primavera non esegue la scansione del mondo, utilizza una scansione mirata che significa tutto sotto il pacchetto in cui è memorizzata springbootapplication. pertanto questo errore "Considera la definizione di un bean di tipo 'pacchetto' nella tua configurazione [Spring-Boot]" potrebbe apparire perché hai interfacce di servizi in un diverso pacchetto springbootapplication.

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.